#pragma once
#include <math.h>
#include <cstring>
#include <iostream>
#include <fstream>
#include <exception>
#include <algorithm>

#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkSmartPointer.h>
#include <vtkCellArray.h>
#include <vtkUnstructuredGrid.h>
#include <vtkXMLUnstructuredGridWriter.h>
#include <vtkHexahedron.h>

//#include "utils.h"
#include "INP_card.h"
#include "ReadINP.h"
#include "DataStruct.h"
#include "GeneralMethod.h"

#define PI       3.14159265358979323846   // pi

ReadINP* ReadINP::mesh = nullptr;

std::string ReadINP::AnalysisType = "ST";
bool ReadINP::AnalysisDimention3D = true;

ReadINP::ReadINP()
{
	elementNodeMap = {
		std::make_pair(std::string("MASSPOINT"),std::make_pair(1,001)),
		std::make_pair(std::string("C3D8"),std::make_pair(8,308)),
		std::make_pair(std::string("C3D8I"),std::make_pair(8,308)),
		std::make_pair(std::string("C3D8R"),std::make_pair(8,308)),
		std::make_pair(std::string("C3D8H"),std::make_pair(8,308)),
		std::make_pair(std::string("C3D8RH"),std::make_pair(8,308)),
		std::make_pair(std::string("C3D20"),std::make_pair(20,320)),
		std::make_pair(std::string("C3D20R"),std::make_pair(20,320)),
		std::make_pair(std::string("C3D20H"),std::make_pair(20,320)),
		std::make_pair(std::string("C3D20RH"),std::make_pair(20,320)),
		std::make_pair(std::string("C3D6"),std::make_pair(6,306)),
		std::make_pair(std::string("C3D6H"),std::make_pair(6,306)),
		std::make_pair(std::string("C3D15"),std::make_pair(15,315)),
		std::make_pair(std::string("C3D15H"),std::make_pair(15,315)),
		std::make_pair(std::string("C3D4"),std::make_pair(4,304)),
		std::make_pair(std::string("C3D4H"),std::make_pair(4,304)),
		std::make_pair(std::string("C3D10"),std::make_pair(10,310)),
		std::make_pair(std::string("C3D10H"),std::make_pair(10,310)),
		std::make_pair(std::string("C3D10M"),std::make_pair(10,310)),
		std::make_pair(std::string("C3D10I"),std::make_pair(10,310)),
		std::make_pair(std::string("S3"),std::make_pair(3,203)),
		std::make_pair(std::string("S3R"),std::make_pair(3,203)),
		std::make_pair(std::string("S4"),std::make_pair(4,204)),
		std::make_pair(std::string("S4R"),std::make_pair(4,204)),
		std::make_pair(std::string("M3D3"),std::make_pair(3,203)),
		std::make_pair(std::string("M3D4"),std::make_pair(4,204)),
		std::make_pair(std::string("M3D6"),std::make_pair(6,206)),
		std::make_pair(std::string("M3D8"),std::make_pair(8,208)),
		std::make_pair(std::string("B21"),std::make_pair(2,102)),
		std::make_pair(std::string("B31"),std::make_pair(2,102)),
		std::make_pair(std::string("B32"),std::make_pair(3,103)),
		std::make_pair(std::string("B33"),std::make_pair(2,102)),
		std::make_pair(std::string("T3D2"),std::make_pair(2,102)),
		std::make_pair(std::string("SC6R"),std::make_pair(6,306)),
		std::make_pair(std::string("SC8R"),std::make_pair(8,308)),
		std::make_pair(std::string("CPE3"),std::make_pair(3,203)),
		std::make_pair(std::string("CPE3H"),std::make_pair(3,203)),
		std::make_pair(std::string("CPE4"),std::make_pair(4,204)),
		std::make_pair(std::string("CPE4R"),std::make_pair(4,204)),
		std::make_pair(std::string("CPE4H"),std::make_pair(4,204)),
		std::make_pair(std::string("CPE4RH"),std::make_pair(4,204)),
		std::make_pair(std::string("CPE6"),std::make_pair(6,206)),
		std::make_pair(std::string("CPE6H"),std::make_pair(6,206)),
		std::make_pair(std::string("CPE8"),std::make_pair(8,208)),
		std::make_pair(std::string("CPE8H"),std::make_pair(8,208)),
		std::make_pair(std::string("CAX3"),std::make_pair(3,203)),
		std::make_pair(std::string("CAX3H"),std::make_pair(3,203)),
		std::make_pair(std::string("CAX4"),std::make_pair(4,204)),
		std::make_pair(std::string("CAX4H"),std::make_pair(4,204)),
		std::make_pair(std::string("CAX4R"),std::make_pair(4,204)),
		std::make_pair(std::string("CAX4RH"),std::make_pair(4,204)),
		std::make_pair(std::string("CAX6"),std::make_pair(6,206)),
		std::make_pair(std::string("CAX6H"),std::make_pair(6,206)),
		std::make_pair(std::string("CAX6M"),std::make_pair(6,206)),
		std::make_pair(std::string("CAX6MH"),std::make_pair(6,206)),
		std::make_pair(std::string("CAX8"),std::make_pair(8,208)),
		std::make_pair(std::string("CAX8H"),std::make_pair(8,208)),

		std::make_pair(std::string("C3D5"),std::make_pair(5,305)),
		std::make_pair(std::string("CPS3"),std::make_pair(3,203)),
		std::make_pair(std::string("CPS4"),std::make_pair(4,204)),
		std::make_pair(std::string("CPS4R"),std::make_pair(4,204)),
		std::make_pair(std::string("CPS6"),std::make_pair(6,206)),
		std::make_pair(std::string("CPS8"),std::make_pair(8,208)),
		std::make_pair(std::string("R3D3"),std::make_pair(3,203)),
		std::make_pair(std::string("R3D4"),std::make_pair(4,204)),
		std::make_pair(std::string("STRI65"),std::make_pair(6,206)),
		std::make_pair(std::string("S8R"),std::make_pair(8,208)),

		std::make_pair(std::string("CONN3D2"),std::make_pair(2,102)),//! two-node spring 
		std::make_pair(std::string("DCOUP3D"),std::make_pair(1,001)),//! distributing coupling(master node)
		std::make_pair(std::string("SPRING1"),std::make_pair(1,001)),//! ground spring
		std::make_pair(std::string("SPRING2"),std::make_pair(2,102)),//! two-node spring 
		std::make_pair(std::string("DASHPOTA"),std::make_pair(2,102)),//! two-node axial dashpot

		std::make_pair(std::string("AC3D10"),std::make_pair(10,310)),
		std::make_pair(std::string("AC3D20"),std::make_pair(20,320)),

		//! Thermal special
		std::make_pair(std::string("DC2D3"),std::make_pair(3,203)),
		std::make_pair(std::string("DC2D4"),std::make_pair(4,204)),
		std::make_pair(std::string("DC2D6"),std::make_pair(6,206)),
		std::make_pair(std::string("DC2D8"),std::make_pair(8,208)),

		std::make_pair(std::string("ROTARYIPOINT"),std::make_pair(1,001)),
		std::make_pair(std::string("GAPUNI"),std::make_pair(2,102)),
		std::make_pair(std::string("GAPUNIT"),std::make_pair(2,102)),
		//新增GAP代码-柱坐标系GAP单元类型。
		std::make_pair(std::string("GAPCYL"),std::make_pair(2,102)),

		std::make_pair(std::string("DC3D8"),std::make_pair(8,308)),
		std::make_pair(std::string("DC3D8I"),std::make_pair(8,308)),
		std::make_pair(std::string("DC3D8R"),std::make_pair(8,308)),
		std::make_pair(std::string("DC3D8H"),std::make_pair(8,308)),
		std::make_pair(std::string("DC3D8RH"),std::make_pair(8,308)),
		std::make_pair(std::string("DC3D20"),std::make_pair(20,320)),
		std::make_pair(std::string("DC3D20R"),std::make_pair(20,320)),
		std::make_pair(std::string("DC3D20H"),std::make_pair(20,320)),
		std::make_pair(std::string("DC3D20RH"),std::make_pair(20,320)),
		std::make_pair(std::string("DC3D6"),std::make_pair(6,306)),
		std::make_pair(std::string("DC3D6H"),std::make_pair(6,306)),
		std::make_pair(std::string("DC3D15"),std::make_pair(15,315)),
		std::make_pair(std::string("DC3D15H"),std::make_pair(15,315)),
		std::make_pair(std::string("DC3D4"),std::make_pair(4,304)),
		std::make_pair(std::string("DC3D4H"),std::make_pair(4,304)),
		std::make_pair(std::string("DC3D10"),std::make_pair(10,310)),
		std::make_pair(std::string("DC3D10H"),std::make_pair(10,310)),
		std::make_pair(std::string("DC3D10M"),std::make_pair(10,310)),
		std::make_pair(std::string("DC3D10I"),std::make_pair(10,310)),
		std::make_pair(std::string("DS3"),std::make_pair(3,203)),
		std::make_pair(std::string("DS3R"),std::make_pair(3,203)),
		std::make_pair(std::string("DS4"),std::make_pair(4,204)),
		std::make_pair(std::string("DS4R"), std::make_pair(4, 204)),
		std::make_pair(std::string("DCAX4"), std::make_pair(4, 204)),
		std::make_pair(std::string("DCAX4H"), std::make_pair(4, 204)),
		std::make_pair(std::string("DCAX4R"), std::make_pair(4, 204)),
		std::make_pair(std::string("DCAX4RH"), std::make_pair(4, 204)),
	};

	elementFormulationMap = {
		std::make_pair(std::string("C3D8"),"Hex8"),
		std::make_pair(std::string("C3D8I"),"Hex8ICR"),
		std::make_pair(std::string("C3D8R"),"Hex8R"),
		std::make_pair(std::string("C3D8H"),"Hex8H"),
		std::make_pair(std::string("C3D8RH"),"Hex8RH"),
		std::make_pair(std::string("C3D20"),"Hex20"),
		std::make_pair(std::string("C3D20R"),"Hex20R"),
		std::make_pair(std::string("C3D20H"),"Hex20H"),
		std::make_pair(std::string("C3D20RH"),"Hex20RH"),
		std::make_pair(std::string("C3D6"),"Wedge6"),
		std::make_pair(std::string("C3D6H"),"Wedge6H"),
		std::make_pair(std::string("C3D15"),"Wedge15"),
		std::make_pair(std::string("C3D15H"),"Wedge15H"),
		std::make_pair(std::string("C3D4"),"Tet4"),
		std::make_pair(std::string("C3D4H"),"Tet4H"),
		std::make_pair(std::string("C3D10"),"Tet10"),
		std::make_pair(std::string("C3D10H"),"Tet10H"),
		std::make_pair(std::string("S3"),"Shell3"),
		std::make_pair(std::string("S3R"),"Shell3"),
		std::make_pair(std::string("S4"),"Shell4"),
		std::make_pair(std::string("S4R"),"Shell4"),
		std::make_pair(std::string("M3D3"),"Tri3M"),
		std::make_pair(std::string("M3D4"),"Quad4M"),
		std::make_pair(std::string("M3D6"),"Tri6M"),
		std::make_pair(std::string("M3D8"),"Quad8M"),
		std::make_pair(std::string("B21"),"Beam2"),
		std::make_pair(std::string("B31"),"Beam2"),
		std::make_pair(std::string("B32"),"Beam3"),
		std::make_pair(std::string("B33"),"BeamEuler"),
		std::make_pair(std::string("T3D2"),"Truss2"),
		std::make_pair(std::string("SC6R"),"SolidShell6"),
		std::make_pair(std::string("SC8R"),"SolidShell8"),
		std::make_pair(std::string("CPE3"),"Tri3PE"),
		std::make_pair(std::string("CPE3H"),"Tri3PEH"),
		std::make_pair(std::string("CPE4"),"Quad4PE"),
		std::make_pair(std::string("CPE4H"),"Quad4PEH"),
		std::make_pair(std::string("CPE6"),"Tri6PE"),
		std::make_pair(std::string("CPE6H"),"Tri6PEH"),
		std::make_pair(std::string("CPE8"),"Quad8PE"),
		std::make_pair(std::string("CPE8H"),"Quad8PEH"),
		std::make_pair(std::string("CAX3"),"Tri3Axis"),
		std::make_pair(std::string("CAX3H"),"Tri3AxisH"),
		std::make_pair(std::string("CAX4"),"Quad4Axis"),
		std::make_pair(std::string("CAX4H"),"Quad4AxisH"),
		std::make_pair(std::string("CAX6"),"Tri6Axis"),
		std::make_pair(std::string("CAX6H"),"Tri6AxisH"),
		std::make_pair(std::string("CAX6M"),"Tri6Axis"),
		std::make_pair(std::string("CAX6MH"),"Tri6AxisH"),
		std::make_pair(std::string("CAX8"),"Quad8Axis"),
		std::make_pair(std::string("CAX8H"),"Quad8AxisH"),
		std::make_pair(std::string("SPRING2"),"spring2"),

		//! ?
		std::make_pair(std::string("C3D5"),"Pyramid5"),
		std::make_pair(std::string("CPS3"),"Tri3PS"),
		std::make_pair(std::string("CPS4"),"Quad4PS"),
		std::make_pair(std::string("CPS4R"),"Quad4PS"),
		std::make_pair(std::string("CPS6"),"Tri6PS"),
		std::make_pair(std::string("CPS8"),"Quad8PS"),
		std::make_pair(std::string("R3D3"),"Tri3M"),
		std::make_pair(std::string("R3D4"),"Quad4M"),
		std::make_pair(std::string("STRI65"),"HughesLiu6"),
		std::make_pair(std::string("S8R"),"HughesLiu8R"),
		std::make_pair(std::string("CONN3D2"),"SPRING"),
		std::make_pair(std::string("DCOUP3D"),"Point"),
		std::make_pair(std::string("SPRING1"),"Point"),
		std::make_pair(std::string("C3D10M"),"Tet10"),
		std::make_pair(std::string("C3D10I"),"Tet10"),
		std::make_pair(std::string("CPE4R"),"Quad4PE"),
		std::make_pair(std::string("CPE4RH"),"Quad4PEH"),
		std::make_pair(std::string("CAX4R"),"Quad4Axis"),
		std::make_pair(std::string("CAX4RH"),"Quad4AxisH"),

		//! Thermal
		std::make_pair(std::string("DC3D8"),"THHex8"),
		std::make_pair(std::string("DC3D8I"),"THHex8ICR"),
		std::make_pair(std::string("DC3D8R"),"THHex8R"),
		std::make_pair(std::string("DC3D8H"),"THHex8H"),
		std::make_pair(std::string("DC3D8RH"),"THHex8RH"),
		std::make_pair(std::string("DC3D20"),"THHex20"),
		std::make_pair(std::string("DC3D20R"),"THHex20R"),
		std::make_pair(std::string("DC3D20H"),"THHex20H"),
		std::make_pair(std::string("DC3D20RH"),"THHex20RH"),
		std::make_pair(std::string("DC3D6"),"THWedge6"),
		std::make_pair(std::string("DC3D6H"),"THWedge6H"),
		std::make_pair(std::string("DC3D15"),"THWedge15"),
		std::make_pair(std::string("DC3D15H"),"THWedge15H"),
		std::make_pair(std::string("DC3D4"),"THTet4"),
		std::make_pair(std::string("DC3D4H"),"THTet4H"),
		std::make_pair(std::string("DC3D10"),"THTet10"),
		std::make_pair(std::string("DC3D10H"),"THTet10H"),
		std::make_pair(std::string("DS3"),"THShell3"),
		std::make_pair(std::string("DS3R"),"THShell3"),
		std::make_pair(std::string("DS4"),"THShell4"),
		std::make_pair(std::string("DS4R"),"THShell4"),

		std::make_pair(std::string("DC2D3"),"THTri3"),
		std::make_pair(std::string("DC2D4"),"THQuad4"),
		std::make_pair(std::string("DC2D6"),"THTri6"),
		std::make_pair(std::string("DC2D8"),"THQuad8"),

		//新增gap代码。GAP单元类型对应的simdroid单元类型。因为在simdroid中为接触。因此暂将其转换成spring2类型。
		std::make_pair(std::string("GAPUNI"), "spring2"),
		std::make_pair(std::string("GAPUNIT"), "spring2"),
		std::make_pair(std::string("GAPCYL"), "spring2"),
		//新增MASS单元类型对应的simdroid单元类型。为"Point"
		std::make_pair(std::string("MASS"),"Point"),
		std::make_pair(std::string("MASSPOINT"), "Point"),
	};

	faceMaps = {
		std::make_pair("S1",0),
		std::make_pair("S2" , 1),
		std::make_pair("S3" , 2),
		std::make_pair("S4" , 3),
		std::make_pair("S5" , 4),
		std::make_pair("S6" , 5),
		std::make_pair("SPOS" , 0),
		std::make_pair("SNEG" , 1) };

	abaqus_type_to_meshio_type =
	{
		make_pair(1,"vertex"),
		make_pair(102,"line"),
		make_pair(103,"line3"),
		make_pair(203,"triangle"),
		make_pair(204,"quad"),
		make_pair(206,"triangle6"),
		make_pair(208,"quad8"),
		make_pair(304,"tetra"),
		make_pair(306,"wedge"),
		make_pair(308,"hexahedron"),
		make_pair(310,"tetra10"),
		make_pair(315,"wedge"),
		make_pair(320,"hexahedron20")
	};
	//在inp的surface set中，区分单元类型。（高阶二维单元某条边的节点个数和soild单元某个面的节点个数相同。）
	highOrder2DElement= { "CPE6" ,"CPE6H" ,"CPE8" ,"CPE8H" ,"CAX6" ,"CAX6H" ,"CAX8" ,"CAX8H" };

	cellIndex = 0;
	cellId = 1;
	nodeId = 1;

	partNumberID = 0;

	this->systemMeshUsed = nullptr;

	unhandleSurface.clear();
	readOnce = false;
	errorMsg = "";

	isInPartKey = false;

	isInAssmbly = false;

	translation[0] = 0.0; translation[1] = 0.0; translation[2] = 0.0;
	rotation[0] = 1.0; rotation[1] = 0.0; rotation[2] = 0.0;
	rotation[3] = 0.0; rotation[4] = 1.0; rotation[5] = 0.0;
	rotation[6] = 0.0; rotation[7] = 0.0; rotation[8] = 1.0;

	componentId = 1;
}

ReadINP::~ReadINP()
{
	if (mesh != nullptr)
	{
		partIndex.resize(0);
		allNodeId.resize(0);
		allNodeCoor.resize(0);

		allElementId.resize(0);
		allElementNode.resize(0);
		allElementType.resize(0);
		elementFormulation.resize(0);
		elementIndex.resize(0);

		allNodeSetName.resize(0);
		nodeSetData.resize(0);

		allElementSetName.resize(0);
		elementSetData.resize(0);

		delete mesh;
	}
}

bool ReadINP::readInpMesh(std::string inpPath)
{
	int lineNumerId = 0, errorNumerLine = 0;

	try
	{
		std::ifstream inpStream;
		inpStream.open(inpPath, std::ios::in);
		if (!inpStream.is_open())
		{
			return false;
		}

		//! 1 for "*NODE" ;2 for "*ELEMENT";3 for "*";4 for "*MATERIAL";5 for "*NSET" OR "*ELSET";6 for "*SURFACE"
		//! 7 for "*END PART" ;
		int lineFlag = 0;
		bool partClassify = false;
		bool parseOnce = true, parseStarted = false;
		bool lastPartEnd = false;
		std::vector<std::string> nodeBlock, elementBlock, surfaceBlock, setBlock, materialBlock, instanceBlock;
		std::vector<std::string> sectionBlock, contactBlock, initialBlock, constraintBlock, stepBlock, loadBlock;

		const char* startCharacter = "*";

		std::string lineBuffer;
		std::vector<std::string> keyLine;
		while (std::getline(inpStream, lineBuffer))
		{
			std::string::size_type pos = lineBuffer.find_last_of('\r');
			if (pos != std::string::npos)
			{
				lineBuffer.erase(pos);
			}

			lineNumerId++;

			if (lineBuffer.empty() && lineFlag != 8)
			{
				continue;
			}

			if (lineBuffer[0] == startCharacter[0])
			{
				if (lineBuffer[1] == startCharacter[0])
				{
					continue;
				}

				GeneralMethod::split(keyLine, lineBuffer, ",");
				std::transform(keyLine[0].begin(), keyLine[0].end(), keyLine[0].begin(), ::toupper);
				if (strcmp(keyLine[0].c_str(), "*NODE") == 0
					|| strcmp(keyLine[0].c_str(), "*SYSTEM") == 0)
				{
					lineFlag = 1;
					parseOnce = !parseOnce;
					parseStarted = true;
				}
				else if (strcmp(keyLine[0].c_str(), "*ELEMENT") == 0)
				{
					lineFlag = 2;
					parseOnce = !parseOnce;
					parseStarted = true;
				}
				else if (strcmp(keyLine[0].c_str(), "*NSET") == 0)
				{
					lineFlag = 5;
					parseOnce = !parseOnce;
					parseStarted = true;
				}
				else if (strcmp(keyLine[0].c_str(), "*ELSET") == 0)
				{
					lineFlag = 5;
					parseOnce = !parseOnce;
					parseStarted = true;
				}
				else if (strcmp(keyLine[0].c_str(), "*SURFACE") == 0)
				{
					lineFlag = 6;
					parseOnce = !parseOnce;
					parseStarted = true;
				}
				else if (strcmp(keyLine[0].c_str(), "*PART") == 0)
				{
					isInPartKey = true;
					elementInternalSetData.clear();
					elementInternalSetName.clear();
					if (keyLine.size() > 1)
					{
						partName.emplace_back(GeneralMethod::GetName(keyLine[1]));
					}
					lineFlag = 3;
				}
				else if (strcmp(keyLine[0].c_str(), "*END PART") == 0)
				{
					lineFlag = 7;
					partClassify = true;
					parseOnce = !parseOnce;
					parseStarted = true;
				}
				else if (strcmp(keyLine[0].c_str(), "*ASSEMBLY") == 0)
				{
					isInAssmbly = true;

					lineFlag = 7;
					partClassify = true;
					parseOnce = !parseOnce;
					parseStarted = true;
				}
				else if (strcmp(keyLine[0].c_str(), "*END ASSEMBLY") == 0)
				{
					isInAssmbly = false;

					lineFlag = 7;
					partClassify = true;
					parseOnce = !parseOnce;
					parseStarted = true;
				}
				else
				{
					keyWordsUnsupport.emplace_back(keyLine[0]);
					lineFlag = 3;
				}

				if (parseOnce && parseStarted)
				{
					if (nodeBlock.size() > 0)
					{
						ParseSingleNodeBlock(nodeBlock);

						nodeBlock.resize(0);
					}

					if (elementBlock.size() > 0)
					{
						ParseSingleElementBlock(elementBlock);

						elementBlock.resize(0);
					}

					if (setBlock.size() > 0)
					{
						ParseSingleSetBlock(setBlock);
						setBlock.resize(0);
					}


					if (instanceBlock.size() > 0)
					{
						ParseSingleInstance(instanceBlock);
						instanceBlock.resize(0);
					}

					parseOnce = !parseOnce;
					parseStarted = false;
				}

				if (lineFlag != 3)
				{
					errorNumerLine = lineNumerId;
				}

				if (partClassify)
				{
					partClassify = false;
				}
			}

			switch (lineFlag)
			{
			case 1:
				nodeBlock.emplace_back(lineBuffer);
				break;
			case 2:
				elementBlock.emplace_back(lineBuffer);
				break;
			case 3:
				if (lastPartEnd)
				{
					partNumberID++;
				}
				lastPartEnd = false;
				break;
			case 4:
				materialBlock.emplace_back(lineBuffer);
				break;
			case 5:
				setBlock.emplace_back(lineBuffer);
				break;
			case 6:
				surfaceBlock.emplace_back(lineBuffer);
				break;
			case 7:
				lastPartEnd = true;
				isInPartKey = false;
				//  partNumberID++;
				break;
			case 8:
				sectionBlock.emplace_back(lineBuffer);
				break;
			case 9:
				contactBlock.emplace_back(lineBuffer);
				break;
			case 10:
				initialBlock.emplace_back(lineBuffer);
				break;
			case 11:
				constraintBlock.emplace_back(lineBuffer);
				break;
			case 12:
				stepBlock.emplace_back(lineBuffer);
				break;
			case 13:
				loadBlock.emplace_back(lineBuffer);
				break;
			case 14:
				instanceBlock.emplace_back(lineBuffer);
				break;
			default:
				break;
			}
		}

		if (nodeBlock.size() > 0)
		{
			ParseSingleNodeBlock(nodeBlock);

			nodeBlock.resize(0);
		}

		if (elementBlock.size() > 0)
		{
			ParseSingleElementBlock(elementBlock);

			elementBlock.resize(0);
		}

		if (setBlock.size() > 0)
		{
			ParseSingleSetBlock(setBlock);
			setBlock.resize(0);
		}

		if (instanceBlock.size() > 0)
		{
			ParseSingleInstance(instanceBlock);
			instanceBlock.resize(0);
		}

		readOnce = true;


		if (allElementType.size() == elementIndex.size())
		{
			elementIndex.emplace_back(allElementNode.size());
		}

		return true;
	}
	catch (std::exception& e)
	{
		//Import::MeshInterface.keywordsUnsupport.emplace_back(std::string(e.what()) + "Parse error in line " + std::to_string(errorNumerLine) + ".\n");
		return false;
	}
	catch (...)
	{
		//Import::MeshInterface.keywordsUnsupport.emplace_back("Parse error in line " + std::to_string(errorNumerLine) + ".\n");
		return false;
	}
}

ReadINP* ReadINP::GetInstance()
{
	if (ReadINP::mesh == nullptr)
	{
		ReadINP::mesh = new ReadINP();
	}
	return ReadINP::mesh;
}

void ReadINP::ParseNodeSystem(std::vector<std::string>& block)
{
	if (block.size() < 2)
	{
		return;
	}
	auto linaVector = [](const std::vector<double>& a, const std::vector<double>& b)-> std::vector<double>
	{
		std::vector<double> c(3);
		double factor = sqrt(pow(b[0] - a[0], 2) + pow(b[1] - a[1], 2) + pow(b[2] - a[2], 2));
		c[0] = (b[0] - a[0]) / factor; c[1] = (b[1] - a[1]) / factor; c[2] = (b[2] - a[2]) / factor;
		return c;
	};
	auto cross3dVector = [](const std::vector<double>& a, const std::vector<double>& b)-> std::vector<double>
	{
		std::vector<double> c(3);
		c[0] = a[1] * b[2] - a[2] * b[1];
		c[1] = a[2] * b[0] - a[0] * b[2];
		c[2] = a[0] * b[1] - a[1] * b[0];
		return c;
	};

	if (systemMeshUsed == nullptr)
	{
		systemMeshUsed = new SYSTEMCoor;
	}
	std::vector<std::string> valueLine;
	GeneralMethod::split(valueLine, block[1], ",");
	systemMeshUsed->a = { atof(valueLine[0].c_str()),atof(valueLine[1].c_str()) ,atof(valueLine[2].c_str()) };
	std::vector<double> b = { atof(valueLine[3].c_str()),atof(valueLine[4].c_str()) ,atof(valueLine[5].c_str()) };
	if (block.size() > 2)
	{
		valueLine.clear();
		GeneralMethod::split(valueLine, block[2], ",");
		std::vector<double> c = { atof(valueLine[0].c_str()),atof(valueLine[1].c_str()) ,atof(valueLine[2].c_str()) };
		systemMeshUsed->x = linaVector(systemMeshUsed->a, b);
		//std::vector<double> temp = linaVector(systemMeshUsed->a, c);
		//systemMeshUsed->z = cross3dVector(systemMeshUsed->x, temp);
		//systemMeshUsed->y = cross3dVector(systemMeshUsed->z, systemMeshUsed->x);
		//修改局部坐标系x y z 分量的计算方式。
		systemMeshUsed->y = linaVector(systemMeshUsed->a, c);
		systemMeshUsed->z = cross3dVector(systemMeshUsed->x, systemMeshUsed->y);
	}
	else
	{
		systemMeshUsed->z = { 0.0,0.0,1.0 };
		systemMeshUsed->x = linaVector(systemMeshUsed->a, b);
		systemMeshUsed->y = cross3dVector(systemMeshUsed->z, systemMeshUsed->x);
	}
}

void ReadINP::ParseSingleNodeBlock(std::vector<std::string>& block)
{
	if (block.size() < 2)
	{
		return;
	}

	bool creatNodeSet = false;
	std::vector<int> creatNodeSetData;
	std::vector<std::string> keyLine;
	GeneralMethod::split(keyLine, block[0], ",");
	std::string nodeSet = "";
	std::string sysType = "";

	std::transform(keyLine[0].begin(), keyLine[0].end(), keyLine[0].begin(), ::toupper);
	if (strcmp(keyLine[0].c_str(), "*SYSTEM") == 0)
	{
		ParseNodeSystem(block);
		return;
	}
	if (keyLine.size()>1)
	{
			std::string result = GeneralMethod::GetLabel(keyLine[1]);
			if (strcmp(result.c_str(), "SYSTEM") == 0)
			{
				sysType = GeneralMethod::GetName(keyLine[1]);
			}
	}

	for (auto s : keyLine)
	{
		std::string result = GeneralMethod::GetLabel(s);
		if (strcmp(result.c_str(), "NSET") == 0)
		{
			nodeSet = GeneralMethod::GetName(s);
			creatNodeSet = true;
		}
	}

	if (creatNodeSet)
	{
		creatNodeSetData.reserve(block.size() - 1);
	}

	int startCoorStory = allNodeCoor.size();
	allNodeCoor.resize(startCoorStory + (block.size() - 1) * 3);

	std::vector<std::string> dataUsed;
	if (systemMeshUsed != nullptr)
	{
		if (strcmp(sysType.c_str(), "C")==0)//如果节点的坐标系是C；证明是在柱坐标系下的节点坐标。
		{
			for (int i=1;i<block.size();i++)
			{
				GeneralMethod::split(dataUsed,block[i],",");
				if (dataUsed.size()==4)
				{
					int inpNodeId = atoi(dataUsed[0].c_str());
					nodeIdInpToIBEMap[std::make_pair(partNumberID,inpNodeId)]=nodeId;
					if (creatNodeSet)
					{
						creatNodeSetData.emplace_back(nodeId);
					}
					nodeId++;
					double xInC = atof(dataUsed[1].c_str()); double yInC = atof(dataUsed[2].c_str()); double zInC = atof(dataUsed[3].c_str());
					//柱坐标系先转换成直角坐标系
					double x = xInC * cos(yInC * PI / 180.0); double y = xInC * sin(yInC * PI / 180.0); double z = z;
					//在局部坐标系下的投影向量值
					double xResult = x * systemMeshUsed->x[0] + y * systemMeshUsed->y[0] + z * systemMeshUsed->z[0];
					double yResult = x * systemMeshUsed->x[1] + y * systemMeshUsed->y[1] + z * systemMeshUsed->z[1];
					double zResult = x * systemMeshUsed->x[2] + y * systemMeshUsed->y[2] + z * systemMeshUsed->z[2];

					//局部坐标系原点坐标+在局部坐标系下的投影分量=全局坐标系下的坐标值
					allNodeCoor[startCoorStory] = xResult + systemMeshUsed->a[0];
					startCoorStory++;
					allNodeCoor[startCoorStory] = yResult + systemMeshUsed->a[1];
					startCoorStory++;
					allNodeCoor[startCoorStory] = zResult + systemMeshUsed->a[2];
					startCoorStory++;
				}
				else if (dataUsed.size() == 3)
				{
					int inpNodeId = atoi(dataUsed[0].c_str());
					nodeIdInpToIBEMap[std::make_pair(partNumberID, inpNodeId)] = nodeId;
					if (creatNodeSet)
					{
						creatNodeSetData.emplace_back(nodeId);
					}
					nodeId++;
					double xInC = atof(dataUsed[1].c_str()); double yInC = atof(dataUsed[2].c_str()); 
					double x = xInC * cos(yInC * PI / 180.0); double y = xInC * sin(yInC * PI / 180.0); 
					double xResult = x * systemMeshUsed->x[0] + y * systemMeshUsed->y[0] ;
					double yResult = x * systemMeshUsed->x[1] + y * systemMeshUsed->y[1] ;

					allNodeCoor[startCoorStory] = xResult + systemMeshUsed->a[0];
					startCoorStory++;
					allNodeCoor[startCoorStory] = yResult + systemMeshUsed->a[1];
					startCoorStory++;
					allNodeCoor[startCoorStory] = 0.0;
					startCoorStory++;
				}
				else
				{
#ifdef _WIN32
					throw std::exception("Node error");
#else
#ifdef linux
					throw std::exception();
#endif
#endif

				}
				dataUsed.clear();
			}
		}
		else
		{
			for (int i = 1; i < block.size(); i++)
			{
				GeneralMethod::split(dataUsed, block[i], ",");
				if (dataUsed.size() == 4)
				{
					int inpNodeId = atoi(dataUsed[0].c_str());
					nodeIdInpToIBEMap[std::make_pair(partNumberID, inpNodeId)] = nodeId;
					if (creatNodeSet)
					{
						creatNodeSetData.emplace_back(nodeId);
					}

					nodeId++;

					double x = atof(dataUsed[1].c_str()); double y = atof(dataUsed[2].c_str()); double z = atof(dataUsed[3].c_str());

					double xResult = x * systemMeshUsed->x[0] + y * systemMeshUsed->y[0] + z * systemMeshUsed->z[0];
					double yResult = x * systemMeshUsed->x[1] + y * systemMeshUsed->y[1] + z * systemMeshUsed->z[1];
					double zResult = x * systemMeshUsed->x[2] + y * systemMeshUsed->y[2] + z * systemMeshUsed->z[2];

					allNodeCoor[startCoorStory] = xResult + systemMeshUsed->a[0];
					startCoorStory++;
					allNodeCoor[startCoorStory] = yResult + systemMeshUsed->a[1];
					startCoorStory++;
					allNodeCoor[startCoorStory] = zResult + systemMeshUsed->a[2];
					startCoorStory++;
				}
				else if (dataUsed.size() == 3)
				{
					int inpNodeId = atoi(dataUsed[0].c_str());
					nodeIdInpToIBEMap[std::make_pair(partNumberID, inpNodeId)] = nodeId;
					if (creatNodeSet)
					{
						creatNodeSetData.emplace_back(nodeId);
					}

					nodeId++;

					double x = atof(dataUsed[1].c_str()); double y = atof(dataUsed[2].c_str());

					double xResult = x * systemMeshUsed->x[0] + y * systemMeshUsed->y[0];
					double yResult = x * systemMeshUsed->x[1] + y * systemMeshUsed->y[1];

					allNodeCoor[startCoorStory] = xResult + systemMeshUsed->a[0];
					startCoorStory++;
					allNodeCoor[startCoorStory] = yResult + systemMeshUsed->a[1];
					startCoorStory++;
					allNodeCoor[startCoorStory] = 0.0;
					startCoorStory++;
				}
				else
				{
#ifdef _WIN32
					throw std::exception("Node error");
#else
#ifdef linux
					throw std::exception();
#endif
#endif

				}
				dataUsed.clear();
				}
		}
		delete systemMeshUsed;
		systemMeshUsed = nullptr;
	}
	else
	{
		for (int i = 1; i < block.size(); i++)
		{
			GeneralMethod::split(dataUsed, block[i], ",");
			if (dataUsed.size() == 4)
			{
				int inpNodeId = atoi(dataUsed[0].c_str());
				nodeIdInpToIBEMap[std::make_pair(partNumberID, inpNodeId)] = nodeId;
				if (creatNodeSet)
				{
					creatNodeSetData.emplace_back(nodeId);
				}

				nodeId++;

				allNodeCoor[startCoorStory] = atof(dataUsed[1].c_str());
				startCoorStory++;
				allNodeCoor[startCoorStory] = atof(dataUsed[2].c_str());
				startCoorStory++;
				allNodeCoor[startCoorStory] = atof(dataUsed[3].c_str());
				startCoorStory++;
			}
			else if (dataUsed.size() == 3)
			{
				int inpNodeId = atoi(dataUsed[0].c_str());
				nodeIdInpToIBEMap[std::make_pair(partNumberID, inpNodeId)] = nodeId;
				if (creatNodeSet)
				{
					creatNodeSetData.emplace_back(nodeId);
				}

				nodeId++;

				allNodeCoor[startCoorStory] = atof(dataUsed[1].c_str());
				startCoorStory++;
				allNodeCoor[startCoorStory] = atof(dataUsed[2].c_str());
				startCoorStory++;
				allNodeCoor[startCoorStory] = 0.0;
				startCoorStory++;
			}
			else
			{
#ifdef _WIN32
				throw std::exception("Node error");
#else
#ifdef linux
				throw std::exception();
#endif
#endif
			}
			dataUsed.clear();
		}
	}
	if (creatNodeSet)
	{
		nodeSetNameMap[nodeSet] = allNodeSetName.size();
		allNodeSetName.emplace_back(nodeSet);
		nodeSetData.emplace_back(std::move(creatNodeSetData));
	}
	std::cout << "INFO : Reading Nodes completed" << std::endl;
}

#if 0

void ReadMesh::ParseSingleElementBlock(std::vector<std::string>& block)
{
	if (block.size() < 2)
	{
		return;
	}

	bool creatEleSet = false;
	std::vector<int> creatEleSetData;

	std::vector<std::string> keyLine;
	GeneralMethod::split(keyLine, block[0], ",");
	std::string eleLabel = "", eleSet = "";
	for (auto s : keyLine)
	{
		std::string result = GeneralMethod::GetLabel(s);
		if (strcmp(result.c_str(), "ELSET") == 0)
		{
			eleSet = GeneralMethod::GetName(s);
			creatEleSet = true;
		}
		else if (strcmp(result.c_str(), "TYPE") == 0)
		{
			eleLabel = GeneralMethod::GetName(s);
			std::transform(eleLabel.begin(), eleLabel.end(), eleLabel.begin(), ::toupper);
			if (strcmp(eleLabel.c_str(), "MASS") == 0)
			{
				eleLabel = "MASSPOINT";
			}
		}
	}

	if (elementNodeMap.find(eleLabel) == elementNodeMap.end())
	{
		errorMsg = "Unsupport element type " + eleLabel + " \n";
		return;
	}

	if (strcmp(eleLabel.c_str(), "CONN3D2") == 0 || strcmp(eleLabel.c_str(), "DCOUP3D") == 0 || strcmp(eleLabel.c_str(), "SPRING1") == 0
		|| strcmp(eleLabel.c_str(), "SPRING2") == 0 || strcmp(eleLabel.c_str(), "DASHPOTA") == 0)
	{
		ParseSpecialElementBlock(block);
		//ParseCONN3D2Block(block);
		return;
	}
	//else if (strcmp(eleLabel.c_str(), "DCOUP3D") == 0)
	//{
	//	ParseDCOUP3DBlock(block);
	//	return;
	//}
	//else if (strcmp(eleLabel.c_str(), "SPRING1") == 0)
	//{
	//	ParseSPRING1Block(block);
	//	return;
	//}
	//else if (strcmp(eleLabel.c_str(), "SPRING2") == 0)
	//{
	//	ParseSPRING2Block(block);
	//	return;
	//}
	else if (strcmp(eleLabel.c_str(), "B31") == 0)
	{
		ParseB31Block(block);
		return;
	}

	int numNode = elementNodeMap[eleLabel].first;

	//! unstory
	int cellType = elementNodeMap[eleLabel].second;
	std::string cellFormulation = elementFormulationMap[eleLabel];
	int cellNodeNum = elementNodeMap[eleLabel].first;
	bool firstLine = true;

	std::vector<std::string> valueList;
	GeneralMethod::split(valueList, block[1], ",");
	bool valueOneLine = valueList.size() == (cellNodeNum + 1);

	int storyElement = elementIdInpToIBEMap.size();
	int blockSize = block.size();
	int storyElementNode = allElementNode.size();
	if (valueOneLine)
	{
		int lineNumAdd = storyElement + blockSize - 1;
		if (creatEleSet)
		{
			creatEleSetData.reserve(lineNumAdd);
		}
		allElementTypeName.resize(lineNumAdd);
		allElementType.resize(lineNumAdd);
		elementFormulation.resize(lineNumAdd);
		elementIndex.resize(lineNumAdd);

		allElementNode.resize(storyElementNode + cellNodeNum * (blockSize - 1));
	}
	else
	{
		int lineNumAdd = storyElement + (blockSize - 1) / 2;
		if (creatEleSet)
		{
			creatEleSetData.reserve(lineNumAdd);
		}
		allElementTypeName.resize(lineNumAdd);
		allElementType.resize(lineNumAdd);
		elementFormulation.resize(lineNumAdd);
		elementIndex.resize(lineNumAdd);

		allElementNode.resize(storyElementNode + cellNodeNum * (blockSize - 1) / 2);
	}

	std::vector<std::string> cellNodeList;
	if (valueOneLine)
	{
		for (int i = 1; i < blockSize; i++)
		{
			GeneralMethod::split(cellNodeList, block[i], ",");
			allElementTypeName[storyElement] = eleLabel;
			allElementType[storyElement] = cellType;
			elementFormulation[storyElement] = cellFormulation;
			elementIndex[storyElement] = cellIndex;
			cellIndex += cellNodeNum;

			elementIdInpToIBEMap[std::make_pair(partNumberID, atoi(cellNodeList[0].c_str()))] = cellId;
			storyElement++;

			if (creatEleSet)
			{
				creatEleSetData.emplace_back(cellId);
			}
			allElementId.emplace_back(cellId);
			cellId++;
			for (int j = 1; j < cellNodeList.size(); j++)
			{
				int nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[j].c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadMesh::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[j] + " not found.");
					continue;
				}
				allElementNode[storyElementNode] = nodeIdInIBE;
				storyElementNode++;
			}
			cellNodeList.clear();
		}
	}
	else
	{
		for (int i = 1; i < block.size(); i++)
		{
			GeneralMethod::split(cellNodeList, block[i], ",");
			int j = 0;
			if (firstLine)
			{
				allElementTypeName[storyElement] = eleLabel;
				allElementType[storyElement] = cellType;
				elementFormulation[storyElement] = cellFormulation;
				elementIndex[storyElement] = cellIndex;
				cellIndex += cellNodeNum;

				elementIdInpToIBEMap[std::make_pair(partNumberID, atoi(cellNodeList[0].c_str()))] = cellId;
				storyElement++;

				if (creatEleSet)
				{
					creatEleSetData.emplace_back(cellId);
				}
				allElementId.emplace_back(cellId);
				cellId++;
				j = 1;
			}
			for (; j < cellNodeList.size(); j++)
			{
				int nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[j].c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadMesh::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[j] + " not found.");
					continue;
				}
				allElementNode[storyElementNode] = nodeIdInIBE;
				storyElementNode++;
			}
			firstLine = !firstLine;

			cellNodeList.clear();
		}
	}
	if (creatEleSet)
	{
		elementSetNameMap[eleSet] = allElementSetName.size();
		allElementSetName.emplace_back(eleSet);
		elementSetData.emplace_back(creatEleSetData);
	}
	//! end
}

#endif//! 导入单元不一定是只有两行

void ReadINP::ParseSingleElementBlock(std::vector<std::string>& block)
{
	if (block.size() < 2)
	{
		return;
	}

	bool creatEleSet = false;
	std::vector<int> creatEleSetData;

	std::vector<std::string> keyLine;
	GeneralMethod::split(keyLine, block[0], ",");
	std::string eleLabel = "", eleSet = "";
	for (auto s : keyLine)
	{
		std::string result = GeneralMethod::GetLabel(s);
		if (strcmp(result.c_str(), "ELSET") == 0)
		{
			eleSet = GeneralMethod::GetName(s);
			creatEleSet = true;
		}
		else if (strcmp(result.c_str(), "TYPE") == 0)
		{
			eleLabel = GeneralMethod::GetName(s);
			std::transform(eleLabel.begin(), eleLabel.end(), eleLabel.begin(), ::toupper);
			if (strcmp(eleLabel.c_str(), "MASS") == 0 || strcmp(eleLabel.c_str(), "ROTARYI") == 0)
			{
				eleLabel = "MASSPOINT";
			}
		}
	}
	if (!eleSet.empty()) {
		std::cout<<"INFO : Reading Element Set : "<<eleSet<<std::endl;
	}
	if (eleLabel=="B31") {
		for (int i = 1; i < block.size(); i++) {
			vector<string> temp_vec;
			GeneralMethod::split(temp_vec, block[i], ",");
			if (temp_vec.size()>=4) {
				string temp_str;
				temp_str+=(temp_vec[0]+",");
				temp_str+=(temp_vec[1]+",");
				temp_str+=(temp_vec[2]);
				block[i]=temp_str;
			}
		}
	}
	if (elementNodeMap.find(eleLabel) == elementNodeMap.end())
	{
		if (ReadINP::AnalysisType == "TH")
		{//! 说明是热分析
			if (eleLabel.size() > 0 && eleLabel[0] == 'D')
			{
				eleLabel.erase(0, 1);
			}
		}

		if (elementNodeMap.find(eleLabel) == elementNodeMap.end())
		{
			keyWordsUnsupport.push_back(block[0]);
			//errorMsg = "Unsupport element type " + eleLabel + " \n";
			return;
		}
	}

	bool ifMatch = INP_card::If3DAnalysisElement(eleLabel) ^ ReadINP::AnalysisDimention3D;
	if (ifMatch)
	{
#if defined(IBE_OS_WIN)
		{
			throw std::exception((eleLabel + " error.Analysis dimension is not match the element in the inp file.\n").c_str());
		}
#elif defined(IBE_OS_LINUX)
		{
			Import::MeshInterface.keywordsUnsupport.emplace_back((eleLabel + " error.Analysis dimension is not match the element in the inp file.\n"));
			throw std::exception();
		}
#endif
	}
#if 0


	if (strcmp(eleLabel.c_str(), "CONN3D2") == 0 || /*strcmp(eleLabel.c_str(), "DCOUP3D") == 0 || */strcmp(eleLabel.c_str(), "SPRING1") == 0
		|| strcmp(eleLabel.c_str(), "SPRING2") == 0 || strcmp(eleLabel.c_str(), "DASHPOTA") == 0)
	{
		ParseSpecialElementBlock(block);
		//ParseCONN3D2Block(block);
		return;
	}
	//将DCOUP3D类型单独拿出来处理
	if (strcmp(eleLabel.c_str(), "DCOUP3D") == 0)
	{
		ParseSingleDCOUP3DBlock(block);
		return;
	}
	

	//新增GAP代码
	//增加GAP单元类型的判断条件。
	if (strcmp(eleLabel.c_str(), "GAPUNI") == 0 || strcmp(eleLabel.c_str(), "GAPUNIT") == 0 || strcmp(eleLabel.c_str(), "GAPCYL") == 0)
	{
		ParseSpecialElementBlock_GAP_NotEle(block);
		return;
	}
	//else if (strcmp(eleLabel.c_str(), "DCOUP3D") == 0)
	//{
	//	ParseDCOUP3DBlock(block);
	//	return;
	//}
	//else if (strcmp(eleLabel.c_str(), "SPRING1") == 0)
	//{
	//	ParseSPRING1Block(block);
	//	return;
	//}
	//else if (strcmp(eleLabel.c_str(), "SPRING2") == 0)
	//{
	//	ParseSPRING2Block(block);
	//	return;
	//}
	else if (strcmp(eleLabel.c_str(), "B31") == 0 || strcmp(eleLabel.c_str(), "B21") == 0 || strcmp(eleLabel.c_str(), "B32") == 0)
	{
		ParseB31Block(block);
		return;
	}
#endif
	int numNode = elementNodeMap[eleLabel].first;

	//! unstory
	int cellType = elementNodeMap[eleLabel].second;
	std::string cellFormulation = elementFormulationMap[eleLabel];

	if (ReadINP::AnalysisType == "TH")
	{//! 说明是热分析
		if (cellFormulation.find_first_of("TH") == cellFormulation.npos)
		{
			cellFormulation = "TH" + cellFormulation;
		}
	}

	int cellNodeNum = elementNodeMap[eleLabel].first;
	bool firstLine = true;

	std::vector<std::string> valueList;
	GeneralMethod::split(valueList, block[1], ",");
	bool valueOneLine = valueList.size() == (cellNodeNum + 1);

	int storyElement = elementIdInpToIBEMap.size();
	int blockSize = block.size();
	int storyElementNode = allElementNode.size();
	if (valueOneLine)
	{
		int lineNumAdd = storyElement + blockSize - 1;
		if (creatEleSet)
		{
			creatEleSetData.reserve(lineNumAdd);
		}
		allElementTypeName.resize(lineNumAdd);
		allElementType.resize(lineNumAdd);
		elementFormulation.resize(lineNumAdd);
		elementIndex.resize(lineNumAdd);

		allElementNode.resize(storyElementNode + cellNodeNum * (blockSize - 1));
	}
	else
	{
		int nodeNumberLine = 0, cellNodeLine = 0;
		for (int i = 1; i < 5; i++)
		{
			valueList.clear();
			GeneralMethod::split(valueList, block[i], ",");
			nodeNumberLine += valueList.size();
			if (nodeNumberLine == (cellNodeNum + 1))
			{
				cellNodeLine = i;
				break;
			}
		}

		int lineNumAdd = storyElement + (blockSize - 1) / cellNodeLine;
		if (creatEleSet)
		{
			creatEleSetData.reserve(lineNumAdd);
		}
		allElementTypeName.resize(lineNumAdd);
		allElementType.resize(lineNumAdd);
		elementFormulation.resize(lineNumAdd);
		elementIndex.resize(lineNumAdd);

		allElementNode.resize(storyElementNode + cellNodeNum * (blockSize - 1) / cellNodeLine);
	}

	std::vector<std::string> cellNodeList;
	if (valueOneLine)
	{
		for (int i = 1; i < blockSize; i++)
		{
			GeneralMethod::split(cellNodeList, block[i], ",");
			allElementTypeName[storyElement] = eleLabel;
			allElementType[storyElement] = cellType;
			elementFormulation[storyElement] = cellFormulation;
			elementIndex[storyElement] = cellIndex;
			cellIndex += cellNodeNum;

			elementIdInpToIBEMap[std::make_pair(partNumberID, atoi(cellNodeList[0].c_str()))] = cellId;
			storyElement++;

			if (creatEleSet)
			{
				creatEleSetData.emplace_back(cellId);
			}
			allElementId.emplace_back(cellId);
			cellId++;
			for (int j = 1; j < cellNodeList.size(); j++)
			{
				int nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[j].c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[j] + " not found.");
					continue;
				}
				allElementNode[storyElementNode] = nodeIdInIBE;
				storyElementNode++;
			}
			cellNodeList.clear();
		}
	}
	else
	{
		int thisElementNodeNumber = 0;
		for (int i = 1; i < block.size(); i++)
		{
			GeneralMethod::split(cellNodeList, block[i], ",");
			int j = 0;
			if (firstLine)
			{
				allElementTypeName[storyElement] = eleLabel;
				allElementType[storyElement] = cellType;
				elementFormulation[storyElement] = cellFormulation;
				elementIndex[storyElement] = cellIndex;
				cellIndex += cellNodeNum;

				elementIdInpToIBEMap[std::make_pair(partNumberID, atoi(cellNodeList[0].c_str()))] = cellId;
				storyElement++;

				if (creatEleSet)
				{
					creatEleSetData.emplace_back(cellId);
				}
				allElementId.emplace_back(cellId);
				cellId++;
				j = 1;
				thisElementNodeNumber = 0;
			}
			for (; j < cellNodeList.size(); j++)
			{
				int nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[j].c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[j] + " not found.");
					continue;
				}
				allElementNode[storyElementNode] = nodeIdInIBE;
				storyElementNode++;
				thisElementNodeNumber++;
			}
			if (thisElementNodeNumber == cellNodeNum)
			{
				firstLine = true;
			}
			else
			{
				firstLine = false;
			}

			cellNodeList.clear();
		}
	}
	if (creatEleSet)
	{
		elementSetNameMap[eleSet] = allElementSetName.size();
		allElementSetName.emplace_back(eleSet);
		elementSetData.emplace_back(creatEleSetData);
	}
	//! end
}

void ReadINP::ParseSingleSetBlock(std::vector<std::string>& block)
{
	if (block.size() < 2)
	{
		return;
	}
	std::vector<std::string> keyLine;
	GeneralMethod::split(keyLine, block[0], ",");
	std::string setName = "";
	int type = 0;
	bool generate = false;
	std::string instNameUsed = "";
	bool internalUsed = false;
	for (auto s : keyLine)
	{
		std::string label = GeneralMethod::GetLabel(s);
		if (strcmp(label.c_str(), "NSET") == 0)
		{
			type = 0;
			setName = GeneralMethod::GetName(s);
		}
		else if (strcmp(label.c_str(), "ELSET") == 0)
		{
			type = 1;
			setName = GeneralMethod::GetName(s);
		}
		else if (strcmp(label.c_str(), "GENERATE") == 0)
		{
			generate = true;
		}
		else if (strcmp(label.c_str(), "INSTANCE") == 0)
		{
			instNameUsed = GeneralMethod::GetName(s);
		}
		else if (strcmp(label.c_str(), "INTERNAL") == 0)
		{
			internalUsed = true;
		}
	}

	int partSetUsed = 0;
	if (instNameUsed.empty())
	{
		if (isInPartKey || isInAssmbly)
		{
			partSetUsed = partNumberID;
		}
		else
		{
			partSetUsed = (partNumberID - 1 < 0) ? 0 : (partNumberID - 1);
		}
	}
	else
	{
		partSetUsed = instanceToPart[instNameUsed];
	}

	bool addNodeSys = false;


	std::vector<int> blockData;
	//将inp的节点数据存储起来
	std::vector<int> blockDataInp;
	std::vector<int> busingBlockData;
	if (generate)
	{
		std::vector<std::string> valueLine;
		for (int i = 1; i < block.size(); i++)
		{
			GeneralMethod::split(valueLine, block[i], ",");
			if (valueLine.size() == 3)
			{
				int start = atoi(valueLine[0].c_str());
				int end = atoi(valueLine[1].c_str());
				int gap = atoi(valueLine[2].c_str());

				for (int j = start; j <= end; j += gap)
				{
					if (type == 0)
					{

						int nodeIdInIBE = GetIBENodeIDFromINPID(partSetUsed, j);
						if (nodeIdInIBE == 0)
						{
							ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + std::to_string(j) + " not found.");
							continue;
						}
						blockData.emplace_back(nodeIdInIBE);
					}
					else if (type == 1)
					{
						int ibeElementId = GetIBEElementIDFromINPID(partSetUsed, j);
						if (ibeElementId == 0)
						{
							ReadINP::GetInstance()->warning.push_back("\nElement id " + std::to_string(j) + " not found.");
							continue;
						}
						blockData.emplace_back(ibeElementId);
					}
				}
			}
			valueLine.clear();
		}

		if (type == 0)
		{
			if (isInPartKey)
			{
				setInterMap[std::make_pair(type, setName)] = blockData;
				nodeInternalSetName.emplace_back(setName);
				nodeInternalSetData.emplace_back(blockData);
			}
			else
			{
				nodeSetNameMap[setName] = allNodeSetName.size();
				allNodeSetName.emplace_back(setName);
				nodeSetData.emplace_back(blockData);
			}
		}
		else if (type == 1)
		{
			if (isInPartKey)
			{
				setInterMap[std::make_pair(type, setName)] = blockData;
				elementInternalSetName.emplace_back(setName);
				elementInternalSetData.emplace_back(blockData);
			}
			else
			{
				elementSetNameMap[setName] = allElementSetName.size();
				allElementSetName.emplace_back(setName);
				elementSetData.emplace_back(blockData);
			}
		}
	}
	else
	{
		std::vector<std::string> valueLine;
		GeneralMethod::split(valueLine, block[1], ",");
		blockData.reserve(valueLine.size() * (block.size() - 1));
		busingBlockData.reserve(valueLine.size()* (block.size() - 1));
		valueLine.clear();
		if (type == 0)
		{
			for (int i = 1; i < block.size(); i++)
			{
				GeneralMethod::split(valueLine, block[i], ",");
				bool ifNumber = true;
				ifNumber = atoi(valueLine[0].c_str()) == 0 ? false : true;
				for (auto value : valueLine)
				{
					if (ifNumber)
					{
						int nodeIdInIBE = GetIBENodeIDFromINPID(partSetUsed, atoi(value.c_str()));
						if (nodeIdInIBE == 0)
						{
							ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + value + " not found.");
							continue;
						}
						blockData.emplace_back(nodeIdInIBE);
						//将inp的节点存入到容器中 20240320
						blockDataInp.emplace_back(std::stoi(value));
					}
					else
					{
						std::vector<int> setFind = GetSet(0, value);
						for (auto num : setFind)
						{
							blockData.emplace_back(num);
						}
					}
				}
				valueLine.clear();
			}
			if (isInPartKey)
			{
				setInterMap[std::make_pair(type, setName)] = blockData;
				nodeInternalSetName.emplace_back(setName);
				nodeInternalSetData.push_back(blockData);
			}
			else
			{
				nodeSetNameMap[setName] = allNodeSetName.size();
				allNodeSetName.emplace_back(setName);
				nodeSetData.push_back(blockData);
				nodeSetNameAndDataInp[setName].push_back(blockDataInp);
			}
		}
		else if (type == 1)
		{
			for (int i = 1; i < block.size(); i++)
			{
				GeneralMethod::split(valueLine, block[i], ",");
				bool ifNumber = true;
				ifNumber = atoi(valueLine[0].c_str()) == 0 ? false : true;
				for (auto value : valueLine)
				{
					if (ifNumber)
					{
						int ibeElementId = GetIBEElementIDFromINPID(partSetUsed, atoi(value.c_str()));
						if (ibeElementId == 0)
						{
							ReadINP::GetInstance()->warning.push_back("\nElement id " + value + " not found.");
							busingBlockData.emplace_back(atoi(value.c_str()));
							continue;
						}
						blockData.emplace_back(ibeElementId);
					}
					else
					{
						std::vector<int> setFind = GetSet(1, value);
						for (auto num : setFind)
						{
							blockData.emplace_back(num);
						}
					}
				}
				valueLine.clear();
			}
			//inp set里面的单元在ibe中没有找到。说明可能是busing单元。
			if (busingBlockData.size()>0)
			{
				bushingElementSetName.emplace_back(setName);
				bushingElementSetData.push_back(busingBlockData);

				dcoup3dElementSetName.emplace_back(setName);
				dcoup3dElementSetData.emplace_back(busingBlockData);
				
			}
			if (isInPartKey)
			{
				setInterMap[std::make_pair(type, setName)] = blockData;
				elementInternalSetName.emplace_back(setName);
				elementInternalSetData.push_back(blockData);
			}
			else
			{
				elementSetNameMap[setName] = allElementSetName.size();
				allElementSetName.emplace_back(setName);
				elementSetData.push_back(blockData);
			}
		}
	}
}

//! node element
void ReadINP::ParseSpecialElementBlock(std::vector<std::string>& block)
{
	bool creatEleSet = false;
	std::vector<int> creatEleSetData;

	std::vector<std::string> keyLine;
	GeneralMethod::split(keyLine, block[0], ",");
	std::string eleLabel = "CONN3D2", eleSet = "";
	for (auto s : keyLine)
	{
		std::string result = GeneralMethod::GetLabel(s);
		if (strcmp(result.c_str(), "ELSET") == 0)
		{
			eleSet = GeneralMethod::GetName(s);
			creatEleSet = true;
		}
		else if (strcmp(result.c_str(), "TYPE") == 0)
		{
			eleLabel = GeneralMethod::GetName(s);
			std::transform(eleLabel.begin(), eleLabel.end(), eleLabel.begin(), ::toupper);
		}
	}
	if (strcmp(eleLabel.c_str(),"CONN3D2")==0)
	{

		int blockSize = block.size();
		std::vector<std::string> cellNodeList;
		for (int i=1;i< blockSize;i++)
		{
			GeneralMethod::split(cellNodeList, block[i], ",");
			for (int j=1;j< cellNodeList.size();j++)
			{
				bool isFirstNum = GeneralMethod::isNum(cellNodeList[j]);
				int nodeIdInIBE = 0;
				if (isFirstNum)
				{
					nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[j].c_str()));
					if (nodeIdInIBE == 0)
					{
						ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[j] + " not found.");
						continue;
					}
				}
				else
				{
					std::vector<std::string> nodeIdList;
					GeneralMethod::split(nodeIdList, cellNodeList[j], ".");
					nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(nodeIdList.back().c_str()));
					if (nodeIdInIBE == 0)
					{
						ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + nodeIdList.back() + " not found.");
						continue;
					}
				}
			}
			cellNodeList.clear();		}
		if (creatEleSet)
		{
			bushingElementSetName.emplace_back(eleSet);
			bushingElementSetData.emplace_back(std::move(creatEleSetData));
		}
		return;
	}
	int numNode = elementNodeMap[eleLabel].first;

	//! unstory
	int cellType = elementNodeMap[eleLabel].second;
	std::string cellFormulation = elementFormulationMap[eleLabel];
	int cellNodeNum = elementNodeMap[eleLabel].first;
	bool firstLine = true;

	int storyElement = elementIdInpToIBEMap.size();
	int blockSize = block.size();
	int storyElementNode = allElementNode.size();

	int lineNumAdd = storyElement + blockSize - 1;
	if (creatEleSet)
	{
		creatEleSetData.reserve(lineNumAdd);
	}
	allElementTypeName.resize(lineNumAdd);
	allElementType.resize(lineNumAdd);
	elementFormulation.resize(lineNumAdd);
	elementIndex.resize(lineNumAdd);

	allElementNode.resize(storyElementNode + cellNodeNum * (blockSize - 1));

	std::vector<std::string> cellNodeList;
	for (int i = 1; i < blockSize; i++)
	{

		GeneralMethod::split(cellNodeList, block[i], ",");
		allElementTypeName[storyElement] = eleLabel;
		allElementType[storyElement] = cellType;
		elementFormulation[storyElement] = cellFormulation;
		elementIndex[storyElement] = cellIndex;
		cellIndex += cellNodeNum;

		elementIdInpToIBEMap[std::make_pair(partNumberID, atoi(cellNodeList[0].c_str()))] = cellId;
		storyElement++;

		if (creatEleSet)
		{
			creatEleSetData.emplace_back(cellId);
		}
		allElementId.emplace_back(cellId);
		cellId++;
		for (int j = 1; j < cellNodeList.size(); j++)
		{
			bool isFirstNum = GeneralMethod::isNum(cellNodeList[j]);
			int nodeIdInIBE = 0;
			if (isFirstNum)
			{
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[j].c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[j] + " not found.");
					continue;
				}
			}
			else
			{
				std::vector<std::string> nodeIdList;
				GeneralMethod::split(nodeIdList, cellNodeList[j], ".");
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(nodeIdList.back().c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + nodeIdList.back() + " not found.");
					continue;
				}
			}

			allElementNode[storyElementNode++] = nodeIdInIBE;

		}
		cellNodeList.clear();

	}
	if (creatEleSet)
	{
		elementSetNameMap[eleSet] = allElementSetName.size();
		allElementSetName.emplace_back(eleSet);
		elementSetData.emplace_back(std::move(creatEleSetData));
	}
}

//新增gap代码
//处理element中 TYPE类型为GAPUNI、GAPUNIT、GAPCYL类型的单元数据。将数据存储到allGapElement容器中。
void ReadINP::ParseSpecialElementBlock_GAP(std::vector<std::string>& block)
{
	bool creatEleSet = false;
	std::vector<int> creatEleSetData;

	std::vector<std::string> keyLine;
	GeneralMethod::split(keyLine, block[0], ",");
	std::string eleLabel = "CONN3D2", eleSet = "";

	for (auto s : keyLine)
	{
		std::string result = GeneralMethod::GetLabel(s);
		if (strcmp(result.c_str(), "ELSET") == 0)
		{
			eleSet = GeneralMethod::GetName(s);
			creatEleSet = true;
		}
		else if (strcmp(result.c_str(), "TYPE") == 0)
		{
			eleLabel = GeneralMethod::GetName(s);
			std::transform(eleLabel.begin(), eleLabel.end(), eleLabel.begin(), ::toupper);
		}
	}

	//获取elementNodeMap 容器，key是eleLabel（GAPUNI GAPUNIT GAPCYL）std::make_pair(std::string("GAPUNI"),std::make_pair(2,102)),
	//std::make_pair(std::string("GAPUNIT"), std::make_pair(2, 102)), std::make_pair(std::string("GAPCYL"), std::make_pair(2, 102)),
	//value是一个对组。
	int numNode = elementNodeMap[eleLabel].first;
	int cellType = elementNodeMap[eleLabel].second;
	//std::make_pair(std::string("GAPUNI"), "spring2"),std::make_pair(std::string("GAPUNIT"), "spring2"),std::make_pair(std::string("GAPCYL"), "spring2"),
	//通过inp中的type关键字，找到simdroid对应的type关键字。
	std::string cellFormulation = elementFormulationMap[eleLabel];
	int cellNodeNum = elementNodeMap[eleLabel].first;
	bool firstLine = true;
	//已经存储的单元个数
	int storyElement = elementIdInpToIBEMap.size();
	//读取的单元的行数
	int blockSize = block.size();
	//已经存储的单元对应节点的个数等于allElementNode容器中元素的个数。
	int storyElementNode = allElementNode.size();
	//容器中需要开辟的内存空间大小。等于已经存储的单元的个数+要读取的行数-1.
	int lineNumAdd = storyElement + blockSize - 1;
	//
	if (creatEleSet)
	{
		//为单元set容器开辟空间。
		creatEleSetData.reserve(lineNumAdd);
	}
	//转换前单元名称的容器。
	allElementTypeName.resize(lineNumAdd);
	//转换后单元类型编号的容器
	allElementType.resize(lineNumAdd);
	//转换后单元名称的容器。
	elementFormulation.resize(lineNumAdd);
	elementIndex.resize(lineNumAdd);
	//给allElementNode容器开辟空间。
	allElementNode.resize(storyElementNode + cellNodeNum * (blockSize - 1));

	//创建一个存放string的vector容器。
	std::vector<std::string> cellNodeList;
	//循环处理特殊的单元的每一行。
	for (int i = 1; i < blockSize; i++)
	{

		GeneralMethod::split(cellNodeList, block[i], ",");
		allElementTypeName[storyElement] = eleLabel;
		allElementType[storyElement] = cellType;
		elementFormulation[storyElement] = cellFormulation;
		elementIndex[storyElement] = cellIndex;
		cellIndex += cellNodeNum;

		elementIdInpToIBEMap[std::make_pair(partNumberID, atoi(cellNodeList[0].c_str()))] = cellId;
		storyElement++;

		if (creatEleSet)
		{
			creatEleSetData.emplace_back(cellId);
		}
		allElementId.emplace_back(cellId);
		cellId++;
		for (int j = 1; j < cellNodeList.size(); j++)
		{
			bool isFirstNum = GeneralMethod::isNum(cellNodeList[j]);
			int nodeIdInIBE = 0;
			if (isFirstNum)
			{
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[j].c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[j] + " not found.");
					continue;
				}
			}
			else
			{
				std::vector<std::string> nodeIdList;
				GeneralMethod::split(nodeIdList, cellNodeList[j], ".");
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(nodeIdList.back().c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + nodeIdList.back() + " not found.");
					continue;
				}
			}
			allElementNode[storyElementNode++] = nodeIdInIBE;

		}
		cellNodeList.clear();

	}

	if (creatEleSet)
	{
		elementSetNameMap[eleSet] = allElementSetName.size();
		allElementSetName.emplace_back(eleSet);
		elementSetData.emplace_back(std::move(creatEleSetData));
	}

}

void ReadINP::ParseSpecialElementBlock_GAP_NotEle(std::vector<std::string>& block)
{
	bool creatEleSet = false;
	std::vector<int> creatEleSetData;
	std::vector<std::string> keyLine;
	GeneralMethod::split(keyLine, block[0], ",");
	std::string eleLabel = "CONN3D2", eleSet = "";

	for (auto s : keyLine)
	{
		std::string result = GeneralMethod::GetLabel(s);
		if (strcmp(result.c_str(), "ELSET") == 0)
		{
			eleSet = GeneralMethod::GetName(s);
			creatEleSet = true;
		}
		else if (strcmp(result.c_str(), "TYPE") == 0)
		{
			eleLabel = GeneralMethod::GetName(s);
			std::transform(eleLabel.begin(), eleLabel.end(), eleLabel.begin(), ::toupper);
		}
	}

	if (strcmp(eleLabel.c_str(), "GAPCYL")==0|| strcmp(eleLabel.c_str(), "GAPUNI") == 0|| strcmp(eleLabel.c_str(), "GAPUNIT") == 0)
	{
		int blockSize = block.size();
		std::vector<std::string> cellNodeList;
		for (int i = 1; i < blockSize; i++)
		{
			GeneralMethod::split(cellNodeList, block[i], ",");

			for (int j = 1; j < cellNodeList.size(); j++)
			{
				bool isFirstNum = GeneralMethod::isNum(cellNodeList[j]);
				int nodeIdInIBE = 0;
				if (isFirstNum)
				{
					nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[j].c_str()));
					if (nodeIdInIBE == 0)
					{
						ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[j] + " not found.");
						continue;
					}
				}
				else
				{
					std::vector<std::string> nodeIdList;
					GeneralMethod::split(nodeIdList, cellNodeList[j], ".");
					nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(nodeIdList.back().c_str()));
					if (nodeIdInIBE == 0)
					{
						ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + nodeIdList.back() + " not found.");
						continue;
					}
				}

			}
			cellNodeList.clear();
		}
		if (creatEleSet)
		{
			gapElementSetName.emplace_back(eleSet);
			gapElementSetData.emplace_back(std::move(creatEleSetData));
		}
	}


}

void ReadINP::ParseCONN3D2Block(std::vector<std::string>& block)
{
	bool creatEleSet = false;
	std::vector<int> creatEleSetData;

	std::vector<std::string> keyLine;
	GeneralMethod::split(keyLine, block[0], ",");
	std::string eleLabel = "CONN3D2", eleSet = "";
	for (auto s : keyLine)
	{
		std::string result = GeneralMethod::GetLabel(s);
		if (strcmp(result.c_str(), "ELSET") == 0)
		{
			eleSet = GeneralMethod::GetName(s);
			creatEleSet = true;
		}
	}

	int numNode = elementNodeMap[eleLabel].first;

	//! unstory
	int cellType = elementNodeMap[eleLabel].second;
	std::string cellFormulation = elementFormulationMap[eleLabel];
	int cellNodeNum = elementNodeMap[eleLabel].first;
	bool firstLine = true;

	int storyElement = elementIdInpToIBEMap.size();
	int blockSize = block.size();
	int storyElementNode = allElementNode.size();

	int lineNumAdd = storyElement + blockSize - 1;
	if (creatEleSet)
	{
		creatEleSetData.reserve(lineNumAdd);
	}
	allElementTypeName.resize(lineNumAdd);
	allElementType.resize(lineNumAdd);
	elementFormulation.resize(lineNumAdd);
	elementIndex.resize(lineNumAdd);

	allElementNode.resize(storyElementNode + cellNodeNum * (blockSize - 1));

	std::vector<std::string> cellNodeList;
	for (int i = 1; i < blockSize; i++)
	{

		GeneralMethod::split(cellNodeList, block[i], ",");
		allElementTypeName[storyElement] = eleLabel;
		allElementType[storyElement] = cellType;
		elementFormulation[storyElement] = cellFormulation;
		elementIndex[storyElement] = cellIndex;
		cellIndex += cellNodeNum;

		elementIdInpToIBEMap[std::make_pair(partNumberID, atoi(cellNodeList[0].c_str()))] = cellId;
		storyElement++;

		if (creatEleSet)
		{
			creatEleSetData.emplace_back(cellId);
		}
		allElementId.emplace_back(cellId);
		cellId++;
		for (int j = 1; j < cellNodeList.size(); j++)
		{
			bool isFirstNum = GeneralMethod::isNum(cellNodeList[j]);
			int nodeIdInIBE = 0;
			if (isFirstNum)
			{
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[j].c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[j] + " not found.");
					continue;
				}
			}
			else
			{
				std::vector<std::string> nodeIdList;
				GeneralMethod::split(nodeIdList, cellNodeList[j], ".");
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(nodeIdList.back().c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + nodeIdList.back() + " not found.");
					continue;
				}
			}
			allElementNode[storyElementNode++] = nodeIdInIBE;
		}
		cellNodeList.clear();

		break;
	}

	if (creatEleSet)
	{
		elementSetNameMap[eleSet] = allElementSetName.size();
		allElementSetName.emplace_back(eleSet);
		elementSetData.emplace_back(std::move(creatEleSetData));
	}
}

void ReadINP::ParseDCOUP3DBlock(std::vector<std::string>& block)
{
	bool creatEleSet = false;
	std::vector<int> creatEleSetData;

	std::vector<std::string> keyLine;
	GeneralMethod::split(keyLine, block[0], ",");
	std::string eleLabel = "DCOUP3D", eleSet = "";
	for (auto s : keyLine)
	{
		std::string result = GeneralMethod::GetLabel(s);
		if (strcmp(result.c_str(), "ELSET") == 0)
		{
			eleSet = GeneralMethod::GetName(s);
			creatEleSet = true;
		}
	}

	int numNode = elementNodeMap[eleLabel].first;

	//! unstory
	int cellType = elementNodeMap[eleLabel].second;
	std::string cellFormulation = elementFormulationMap[eleLabel];
	int cellNodeNum = elementNodeMap[eleLabel].first;
	bool firstLine = true;

	int storyElement = elementIdInpToIBEMap.size();
	int blockSize = block.size();
	int storyElementNode = allElementNode.size();

	int lineNumAdd = storyElement + blockSize - 1;
	if (creatEleSet)
	{
		creatEleSetData.reserve(lineNumAdd);
	}
	allElementTypeName.resize(lineNumAdd);
	allElementType.resize(lineNumAdd);
	elementFormulation.resize(lineNumAdd);
	elementIndex.resize(lineNumAdd);

	allElementNode.resize(storyElementNode + cellNodeNum * (blockSize - 1));

	std::vector<std::string> cellNodeList;
	for (int i = 1; i < blockSize; i++)
	{
		GeneralMethod::split(cellNodeList, block[i], ",");
		allElementTypeName[storyElement] = eleLabel;
		allElementType[storyElement] = cellType;
		elementFormulation[storyElement] = cellFormulation;
		elementIndex[storyElement] = cellIndex;
		cellIndex += cellNodeNum;

		elementIdInpToIBEMap[std::make_pair(partNumberID, atoi(cellNodeList[0].c_str()))] = cellId;
		storyElement++;

		if (creatEleSet)
		{
			creatEleSetData.emplace_back(cellId);
		}
		allElementId.emplace_back(cellId);
		cellId++;
		for (int j = 1; j < cellNodeList.size(); j++)
		{
			bool isFirstNum = GeneralMethod::isNum(cellNodeList[j]);
			int nodeIdInIBE = 0;
			if (isFirstNum)
			{
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[j].c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[j] + " not found.");
					continue;
				}
			}
			else
			{
				std::vector<std::string> nodeIdList;
				GeneralMethod::split(nodeIdList, cellNodeList[j], ".");
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(nodeIdList.back().c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + nodeIdList.back() + " not found.");
					continue;
				}
			}
			allElementNode[storyElementNode++] = nodeIdInIBE;

		}
		cellNodeList.clear();
		break;
	}

	if (creatEleSet)
	{
		elementSetNameMap[eleSet] = allElementSetName.size();
		allElementSetName.emplace_back(eleSet);
		elementSetData.emplace_back(std::move(creatEleSetData));
	}
}

void ReadINP::ParseSingleDCOUP3DBlock(std::vector<std::string>& block)
{
	bool creatEleSet = false;
	std::vector<int> creatEleSetData;

	std::vector<std::string> keyLine;
	GeneralMethod::split(keyLine, block[0], ",");
	std::string eleLabel = "DCOUP3D", eleSet = "";
	for (auto s : keyLine)
	{
		std::string result = GeneralMethod::GetLabel(s);
		if (strcmp(result.c_str(), "ELSET") == 0)
		{
			eleSet = GeneralMethod::GetName(s);
		}
	}
	int blockSize = block.size();
	std::vector<std::string> cellNodeList;
	std::vector<int> nodeIdVector;
	for (int i = 1; i < blockSize; i++)
	{
		GeneralMethod::split(cellNodeList, block[i], ",");
		for (int j = 1; j < cellNodeList.size(); j++)
		{
			bool isFirstNum = GeneralMethod::isNum(cellNodeList[j]);
			int nodeIdInIBE = 0;
			if (isFirstNum)
			{
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[j].c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[j] + " not found.");
					continue;
				}
			}
			else
			{
				std::vector<std::string> nodeIdList;
				GeneralMethod::split(nodeIdList, cellNodeList[j], ".");
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(nodeIdList.back().c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + nodeIdList.back() + " not found.");
					continue;
				}
			}
		}
		cellNodeList.clear();
		AddSet(nodeIdVector,0, eleSet+ "_Node",false);
		nodeIdVector.clear();
		break;
	}
}

void ReadINP::ParseSPRING1Block(std::vector<std::string>& block)
{
	bool creatEleSet = false;
	std::vector<int> creatEleSetData;

	std::vector<std::string> keyLine;
	GeneralMethod::split(keyLine, block[0], ",");
	std::string eleLabel = "SPRING1", eleSet = "";
	for (auto s : keyLine)
	{
		std::string result = GeneralMethod::GetLabel(s);
		if (strcmp(result.c_str(), "ELSET") == 0)
		{
			eleSet = GeneralMethod::GetName(s);
			creatEleSet = true;
		}
	}

	int numNode = elementNodeMap[eleLabel].first;

	//! unstory
	int cellType = elementNodeMap[eleLabel].second;
	std::string cellFormulation = elementFormulationMap[eleLabel];
	int cellNodeNum = elementNodeMap[eleLabel].first;
	bool firstLine = true;

	int storyElement = elementIdInpToIBEMap.size();
	int blockSize = block.size();
	int storyElementNode = allElementNode.size();

	int lineNumAdd = storyElement + blockSize - 1;
	if (creatEleSet)
	{
		creatEleSetData.reserve(lineNumAdd);
	}
	allElementTypeName.resize(lineNumAdd);
	allElementType.resize(lineNumAdd);
	elementFormulation.resize(lineNumAdd);
	elementIndex.resize(lineNumAdd);

	allElementNode.resize(storyElementNode + cellNodeNum * (blockSize - 1));

	std::vector<std::string> cellNodeList;
	for (int i = 1; i < blockSize; i++)
	{
		GeneralMethod::split(cellNodeList, block[i], ",");
		allElementTypeName[storyElement] = eleLabel;
		allElementType[storyElement] = cellType;
		elementFormulation[storyElement] = cellFormulation;
		elementIndex[storyElement] = cellIndex;
		cellIndex += cellNodeNum;

		elementIdInpToIBEMap[std::make_pair(partNumberID, atoi(cellNodeList[0].c_str()))] = cellId;
		storyElement++;

		if (creatEleSet)
		{
			creatEleSetData.emplace_back(cellId);
		}
		allElementId.emplace_back(cellId);
		cellId++;
		for (int j = 1; j < cellNodeList.size(); j++)
		{
			bool isFirstNum = GeneralMethod::isNum(cellNodeList[j]);
			int nodeIdInIBE = 0;
			if (isFirstNum)
			{
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[j].c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[j] + " not found.");
					continue;
				}
			}
			else
			{
				std::vector<std::string> nodeIdList;
				GeneralMethod::split(nodeIdList, cellNodeList[j], ".");
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(nodeIdList.back().c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + nodeIdList.back() + " not found.");
					continue;
				}
			}
			allElementNode[storyElementNode++] = nodeIdInIBE;
		}
		cellNodeList.clear();
		break;
	}

	if (creatEleSet)
	{
		elementSetNameMap[eleSet] = allElementSetName.size();
		allElementSetName.emplace_back(eleSet);
		elementSetData.emplace_back(std::move(creatEleSetData));
	}
}

void ReadINP::ParseSPRING2Block(std::vector<std::string>& block)
{

	bool creatEleSet = false;
	std::vector<int> creatEleSetData;

	std::vector<std::string> keyLine;
	GeneralMethod::split(keyLine, block[0], ",");
	std::string eleLabel = "SPRING2", eleSet = "";
	for (auto s : keyLine)
	{
		std::string result = GeneralMethod::GetLabel(s);
		if (strcmp(result.c_str(), "ELSET") == 0)
		{
			eleSet = GeneralMethod::GetName(s);
			creatEleSet = true;
		}
	}

	int numNode = elementNodeMap[eleLabel].first;

	//! unstory
	int cellType = elementNodeMap[eleLabel].second;
	std::string cellFormulation = elementFormulationMap[eleLabel];
	int cellNodeNum = elementNodeMap[eleLabel].first;
	bool firstLine = true;

	int storyElement = elementIdInpToIBEMap.size();
	int blockSize = block.size();
	int storyElementNode = allElementNode.size();

	int lineNumAdd = storyElement + blockSize - 1;
	if (creatEleSet)
	{
		creatEleSetData.reserve(lineNumAdd);
	}
	allElementTypeName.resize(lineNumAdd);
	allElementType.resize(lineNumAdd);
	elementFormulation.resize(lineNumAdd);
	elementIndex.resize(lineNumAdd);

	allElementNode.resize(storyElementNode + cellNodeNum * (blockSize - 1));

	std::vector<std::string> cellNodeList;
	for (int i = 1; i < blockSize; i++)
	{
		GeneralMethod::split(cellNodeList, block[i], ",");
		allElementTypeName[storyElement] = eleLabel;
		allElementType[storyElement] = cellType;
		elementFormulation[storyElement] = cellFormulation;
		elementIndex[storyElement] = cellIndex;
		cellIndex += cellNodeNum;

		elementIdInpToIBEMap[std::make_pair(partNumberID, atoi(cellNodeList[0].c_str()))] = cellId;
		storyElement++;

		if (creatEleSet)
		{
			creatEleSetData.emplace_back(cellId);
		}
		allElementId.emplace_back(cellId);
		cellId++;
		for (int j = 1; j < cellNodeList.size(); j++)
		{
			bool isFirstNum = GeneralMethod::isNum(cellNodeList[j]);
			int nodeIdInIBE = 0;
			if (isFirstNum)
			{
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[j].c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[j] + " not found.");
					continue;
				}
			}
			else
			{
				std::vector<std::string> nodeIdList;
				GeneralMethod::split(nodeIdList, cellNodeList[j], ".");
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(nodeIdList.back().c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + nodeIdList.back() + " not found.");
					continue;
				}
			}
			allElementNode[storyElementNode++] = nodeIdInIBE;
		}
		cellNodeList.clear();
		break;
	}

	if (creatEleSet)
	{
		elementSetNameMap[eleSet] = allElementSetName.size();
		allElementSetName.emplace_back(eleSet);
		elementSetData.emplace_back(std::move(creatEleSetData));
	}
}

void ReadINP::ParseB31Block(std::vector<std::string>& block)
{

	bool creatEleSet = false;
	std::vector<int> creatEleSetData;

	std::vector<std::string> keyLine;
	GeneralMethod::split(keyLine, block[0], ",");
	std::string eleLabel = "B31", eleSet = "";
	for (auto s : keyLine)
	{
		std::string result = GeneralMethod::GetLabel(s);
		if (strcmp(result.c_str(), "ELSET") == 0)
		{
			eleSet = GeneralMethod::GetName(s);
			creatEleSet = true;
		}
		else if (strcmp(result.c_str(), "TYPE") == 0)
		{
			eleLabel = GeneralMethod::GetName(s);
			std::transform(eleLabel.begin(), eleLabel.end(), eleLabel.begin(), ::toupper);
		}
	}

	int numNode = elementNodeMap[eleLabel].first;

	//! unstory
	int cellType = elementNodeMap[eleLabel].second;
	std::string cellFormulation = elementFormulationMap[eleLabel];
	int cellNodeNum = elementNodeMap[eleLabel].first;
	bool firstLine = true;

	int storyElement = elementIdInpToIBEMap.size();
	int blockSize = block.size();
	int storyElementNode = allElementNode.size();

	int lineNumAdd = storyElement + blockSize - 1;
	if (creatEleSet)
	{
		creatEleSetData.reserve(lineNumAdd);
	}
	allElementTypeName.resize(lineNumAdd);
	allElementType.resize(lineNumAdd);
	elementFormulation.resize(lineNumAdd);
	elementIndex.resize(lineNumAdd);

	allElementNode.resize(storyElementNode + cellNodeNum * (blockSize - 1));

	std::vector<std::string> cellNodeList;
	for (int i = 1; i < blockSize; i++)
	{
		B31Element conn3d2;
		conn3d2.type = "B31";
		conn3d2.elementId = cellId;
		conn3d2.elementSet = eleSet;

		GeneralMethod::split(cellNodeList, block[i], ",");
		allElementTypeName[storyElement] = eleLabel;
		allElementType[storyElement] = cellType;
		elementFormulation[storyElement] = cellFormulation;
		elementIndex[storyElement] = cellIndex;
		cellIndex += cellNodeNum;

		elementIdInpToIBEMap[std::make_pair(partNumberID, atoi(cellNodeList[0].c_str()))] = cellId;
		storyElement++;

		if (creatEleSet)
		{
			creatEleSetData.emplace_back(cellId);
		}
		allElementId.emplace_back(cellId);
		cellId++;
		for (int j = 1; j < cellNodeList.size(); j++)
		{
			bool isFirstNum = GeneralMethod::isNum(cellNodeList[j]);
			int nodeIdInIBE = 0;
			if (isFirstNum)
			{
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[j].c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[j] + " not found.");
					continue;
				}
			}
			else
			{
				std::vector<std::string> nodeIdList;
				GeneralMethod::split(nodeIdList, cellNodeList[j], ".");
				nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(nodeIdList.back().c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + nodeIdList.back() + " not found.");
					continue;
				}
			}
			allElementNode[storyElementNode++] = nodeIdInIBE;
			if (j == 1)
			{
				conn3d2.nodeId_1 = nodeIdInIBE;
			}
			else if (j == 2)
			{
				conn3d2.nodeId_2 = nodeIdInIBE;
				break;
			}
		}
		if (cellNodeList.size() == 4 && eleLabel == "B32")
		{
			int nodeIdInIBE = GetIBENodeIDFromINPID(partNumberID, atoi(cellNodeList[3].c_str()));
			if (nodeIdInIBE == 0)
			{
				ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + cellNodeList[3] + " not found.");
				continue;
			}
			conn3d2.addition = conn3d2.nodeId_2;
			conn3d2.nodeId_2 = nodeIdInIBE;

			allElementNode[storyElementNode - 1] = nodeIdInIBE;
			allElementNode[storyElementNode++] = conn3d2.addition;
		}
		cellNodeList.clear();

	}

	if (creatEleSet)
	{
		elementSetNameMap[eleSet] = allElementSetName.size();
		allElementSetName.emplace_back(eleSet);
		elementSetData.emplace_back(std::move(creatEleSetData));
	}
}

void ReadINP::ParseSingleInstance(std::vector<std::string>& block)
{
	std::vector<std::string> keyLine;
	GeneralMethod::split(keyLine, block[0], ",");
	std::string thisPartName = "";
	for (auto s : keyLine)
	{
		std::string result = GeneralMethod::GetLabel(s);
		if (strcmp(result.c_str(), "PART") == 0)
		{
			thisPartName = GeneralMethod::GetName(s);
		}
	}

	if (block.size() == 1)
	{
		return;
	}
	else if (block.size() == 2)
	{
		rotation[0] = 1.0; rotation[1] = 0.0; rotation[2] = 0.0;
		rotation[3] = 0.0; rotation[4] = 1.0; rotation[5] = 0.0;
		rotation[6] = 0.0; rotation[7] = 0.0; rotation[8] = 1.0;

		keyLine.clear();
		GeneralMethod::split(keyLine, block[1], ",");

		if (keyLine.size() != 3)
		{
#ifdef _WIN32
			throw std::exception(("Instance of " + thisPartName + " error.Translation must be three number.\n").c_str());
#else
#ifdef linux
			throw std::exception();
#endif
#endif

		}
		translation[0] = atof(keyLine[0].c_str());
		translation[1] = atof(keyLine[1].c_str());
		translation[2] = atof(keyLine[2].c_str());
	}
	else if (block.size() == 3)
	{
		keyLine.clear();
		GeneralMethod::split(keyLine, block[1], ",");

		if (keyLine.size() != 3)
		{
#ifdef _WIN32
			throw std::exception(("Instance of " + thisPartName + " error.Translation must be three number.\n").c_str());
#else
#ifdef linux
			throw std::exception();
#endif
#endif
		}

		translation[0] = atof(keyLine[0].c_str());
		translation[1] = atof(keyLine[1].c_str());
		translation[2] = atof(keyLine[2].c_str());

		keyLine.clear();
		GeneralMethod::split(keyLine, block[2], ",");

		if (keyLine.size() != 7)
		{
#ifdef _WIN32
			throw std::exception(("Instance of " + thisPartName + " error.Translation must be three number.\n").c_str());
#else
#ifdef linux
			throw std::exception();
#endif
#endif
		}

		double axis[3], thita = 0.0;
		axis[0] = atof(keyLine[3].c_str()) - atof(keyLine[0].c_str());
		axis[1] = atof(keyLine[4].c_str()) - atof(keyLine[1].c_str());
		axis[2] = atof(keyLine[5].c_str()) - atof(keyLine[2].c_str());
		thita = atof(keyLine[6].c_str());
		double a = 1 - cos(thita * PI / 180.0);
		double c = cos(thita * PI / 180.0);
		double s = sin(thita * PI / 180.0);

		rotation[0] = a * axis[0] * axis[0] + c;
		rotation[1] = a * axis[0] * axis[1] - s * axis[2];
		rotation[2] = a * axis[0] * axis[2] + s * axis[1];
		rotation[3] = a * axis[0] * axis[1] + s * axis[2];
		rotation[4] = a * axis[1] * axis[1] + c;
		rotation[5] = a * axis[1] * axis[2] - s * axis[0];
		rotation[6] = a * axis[0] * axis[2] - s * axis[1];
		rotation[7] = a * axis[1] * axis[2] + s * axis[0];
		rotation[8] = a * axis[2] * axis[2] + c;
	}

	bool usedTrans = false;
	int partID = FindPartNum(thisPartName);
	double nodeCoorTemp[3];
	for (auto iter : nodeIdInpToIBEMap)
	{
		if (iter.first.first == partID)
		{
			usedTrans = true;
			int nodeStartIndex = iter.second * 3 - 3;
			double* coord = &allNodeCoor[nodeStartIndex];

			nodeCoorTemp[0] = coord[0];
			nodeCoorTemp[1] = coord[1];
			nodeCoorTemp[2] = coord[2];

			coord[0] = rotation[0] * nodeCoorTemp[0] + rotation[1] * nodeCoorTemp[1] + rotation[2] * nodeCoorTemp[2] + translation[0];
			coord[1] = rotation[3] * nodeCoorTemp[0] + rotation[4] * nodeCoorTemp[1] + rotation[5] * nodeCoorTemp[2] + translation[1];
			coord[2] = rotation[6] * nodeCoorTemp[0] + rotation[7] * nodeCoorTemp[1] + rotation[8] * nodeCoorTemp[2] + translation[2];
		}
	}
	if (!usedTrans)
	{
		if (systemMeshUsed == nullptr)
		{
			systemMeshUsed = new SYSTEMCoor;
		}
		systemMeshUsed->a = std::vector<double>{ translation[0] ,translation[1] ,translation[2] };
		systemMeshUsed->x = std::vector<double>{ rotation[0] ,rotation[1] ,rotation[2] };
		systemMeshUsed->y = std::vector<double>{ rotation[3] ,rotation[4] ,rotation[5] };
		systemMeshUsed->z = std::vector<double>{ rotation[6] ,rotation[7] ,rotation[8] };
	}
}

void ReadINP::split(std::vector<std::string>& result, const std::string& line, const char* sep)
{
	result.clear();
	const size_t sizeLine = line.size();
	const char* str = line.c_str();
	int start = 0;
	int end = 0;

	for (int i = 0; i < sizeLine; i++)
	{
		if (str[i] == sep[0] && i != (sizeLine - 1))
		{
			std::string lineValue(str + start, end);
			GeneralMethod::Trim(lineValue);
			result.emplace_back(lineValue);
			start = i + 1;
			end = 0;
		}
		else
		{
			end++;
		}
	}
	if (end > 0)
	{
		std::string lineValue(str + start, end);
		GeneralMethod::Trim(lineValue);
		result.emplace_back(lineValue);
	}
}

void ReadINP::split(std::vector<const char*>& result, const std::string& line, const char* sep)
{
	const size_t sizeLine = line.size();
	const char* str = line.c_str();
	int start = 0;
	int end = 0;

	for (int i = 0; i < sizeLine; i++)
	{
		if (str[i] == sep[0] && i != (sizeLine - 1))
		{
			result.emplace_back(str + start);
			start = i + 1;
		}
		else
		{
			end++;
		}
	}
	if (end > 0)
	{
		result.emplace_back(str + start);
	}
}

void ReadINP::AddAllElementSet(std::string setName)
{
	AddSet(allElementId, 1, setName);
}

std::string ReadINP::internalSetToOutSet(int type, std::string& setName)
{
	std::string partUsedName = "";
	if (partNumberID != 0)
	{
		std::string partUsedName = partName[partNumberID - 1];
	}

#if 1
	if (setInterMap.find(std::make_pair(type, setName)) != setInterMap.end())
	{
		if (type == 0)//! Node Set
		{
			partUsedName = partUsedName + "_Node_" + setName;
			if (IfHaveSet(type, partUsedName))
			{
				return partUsedName;
			}
			nodeSetNameMap[partUsedName] = allNodeSetName.size();
			allNodeSetName.emplace_back(partUsedName);
			nodeSetData.emplace_back(setInterMap[std::make_pair(type, setName)]);
		}
		else if (type == 1)//! Element Set
		{
			partUsedName = partUsedName + "_Element_" + setName;
			if (IfHaveSet(type, partUsedName))
			{
				return partUsedName;
			}
			elementSetNameMap[partUsedName] = allElementSetName.size();
			allElementSetName.emplace_back(partUsedName);
			elementSetData.emplace_back(setInterMap[std::make_pair(type, setName)]);
		}
		return partUsedName;
	}
#else
	if (type == 0)//! Node Set
	{
		for (int i = 0; i < nodeInternalSetData.size(); i++)
		{
			if (strcmp(nodeInternalSetName[i].c_str(), setName.c_str()) == 0)
			{
				nodeSetNameMap[nodeInternalSetName[i]] = allNodeSetName.size();
				allNodeSetName.emplace_back(nodeInternalSetName[i]);
				nodeSetData.emplace_back(nodeInternalSetData[i]);
			}
		}
	}
	else if (type == 1)//! Element Set
	{
		for (int i = 0; i < elementInternalSetData.size(); i++)
		{
			if (strcmp(elementInternalSetName[i].c_str(), setName.c_str()) == 0)
			{
				elementSetNameMap[elementInternalSetName[i]] = allElementSetName.size();
				allElementSetName.emplace_back(elementInternalSetName[i]);
				elementSetData.emplace_back(elementInternalSetData[i]);
			}
		}
	}
#endif

	return "";
}

std::string ReadINP::sectionSetToUnique(std::string& sourceSetName)
{
	std::string sectionSetName = sourceSetName;

	std::vector<int> setForSectionVec;
	if (isInPartKey)
	{
		for (int i = 0; i < elementInternalSetData.size(); i++)
		{
			if (strcmp(elementInternalSetName[i].c_str(), sourceSetName.c_str()) == 0)
			{
				setForSectionVec.emplace_back(i);
			}
		}
	}
	else
	{
		for (int i = 0; i < elementSetData.size(); i++)
		{
			if (strcmp(allElementSetName[i].c_str(), sourceSetName.c_str()) == 0)
			{
				setForSectionVec.emplace_back(i);
			}
		}
	}
	
	bool is_section_exsist = false;
	std::string temp_section_name = "";
	for (auto&i: elementSetNameMap)
	{
		if (i.first.find(sourceSetName) != std::string::npos && i.first.find("Component_") != std::string::npos)
		{
			is_section_exsist = true;
			temp_section_name = i.first;
			break;
		}
	}
	if (setForSectionVec.size() > 0 && !is_section_exsist)
	{
		std::vector<int> sectionElsetId;
		for (auto id : setForSectionVec)
		{
			if (isInPartKey)
			{
				sectionElsetId.insert(sectionElsetId.end(), elementInternalSetData[id].begin(), elementInternalSetData[id].end());
			}
			else
			{
				sectionElsetId.insert(sectionElsetId.end(), elementSetData[id].begin(), elementSetData[id].end());
			}
		}
		sort(sectionElsetId.begin(), sectionElsetId.end());
		std::vector<int>::iterator iter = std::unique(sectionElsetId.begin(), sectionElsetId.end());
		sectionElsetId.erase(iter, sectionElsetId.end());

		sectionSetName = "Component_" + std::to_string(componentId) + "_" + sourceSetName;
		componentId++;
		elementSetNameMap[sectionSetName] = allElementSetName.size();
		allElementSetName.emplace_back(sectionSetName);
		elementSetData.emplace_back(sectionElsetId);
		return sectionSetName;
	}
	else if (is_section_exsist)
	{
		return temp_section_name;
	}
	else
	{
		return sectionSetName;
	}
}

int ReadINP::FindPartNum(std::string& tempNmae)
{
	for (int i = 0; i < partName.size(); i++)
	{
		if (partName[i] == tempNmae)
		{
			return i;
		}
	}
	return 0;
}

int ReadINP::GetIBENodeIDFromINPID(const int& partNum, const int& inpID)
{
	auto iter = nodeIdInpToIBEMap.find(std::make_pair(partNum, inpID));
	if (iter != nodeIdInpToIBEMap.end())
	{
		return iter->second;
	}
	else
	{
		return 0;
	}
}

int ReadINP::GetIBENodeIDFromINPID(const int& inpID)
{
	std::map<std::pair<int, int>, int>::iterator iter;
	if (isInPartKey)
	{
		iter = nodeIdInpToIBEMap.find(std::make_pair(partNumberID, inpID));
	}
	else
	{
		iter = nodeIdInpToIBEMap.find(std::make_pair((partNumberID - 1) < 0 ? 0 : (partNumberID - 1), inpID));
	}
	if (iter != nodeIdInpToIBEMap.end())
	{
		return iter->second;
	}
	else
	{
		return 0;
	}
}

std::vector<double> ReadINP::GetNodeCoorFromID(const int& inpID, bool ifInpId)
{
	int nodeId = ifInpId ? GetIBENodeIDFromINPID(inpID) : inpID;
	if (nodeId == 0)
	{
		ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + std::to_string(inpID) + " not found.");
		return std::vector<double>{};
	}
	size_t nodeOffset = (nodeId - 1) * 3;
	std::vector<double> nodeCoor = { allNodeCoor[nodeOffset],allNodeCoor[nodeOffset + 1],allNodeCoor[nodeOffset + 2] };
	return nodeCoor;
}

int ReadINP::GetIBEElementIDFromINPID(const int& partNum, const int& inpID)
{
	auto iter = elementIdInpToIBEMap.find(std::make_pair(partNum, inpID));
	if (iter != elementIdInpToIBEMap.end())
	{
		return iter->second;
	}
	else
	{
		return 0;
	}
}

int ReadINP::GetIBEElementIDFromINPID(const int& inpID)
{
	std::map<std::pair<int, int>, int>::iterator iter;
	if (isInPartKey)
	{
		iter = elementIdInpToIBEMap.find(std::make_pair(partNumberID, inpID));
	}
	else
	{
		iter = elementIdInpToIBEMap.find(std::make_pair((partNumberID - 1) < 0 ? 0 : (partNumberID - 1), inpID));
	}
	if (iter != elementIdInpToIBEMap.end())
	{
		return iter->second;
	}
	else
	{
		return 0;
	}
}

std::vector<int> ReadINP::GetInterSet(int type, std::string setName)
{
	std::vector<int> result;
	if (setInterMap.find(std::make_pair(type, setName)) != setInterMap.end())
	{
		std::vector<int>& setValue = setInterMap[std::make_pair(type, setName)];
		result.insert(result.end(), setValue.begin(), setValue.end());
	}

	sort(result.begin(), result.end());
	std::vector<int>::iterator iter = std::unique(result.begin(), result.end());
	result.erase(iter, result.end());
	return result;
}

std::vector<int> ReadINP::GetSet(int type, std::string setName)
{
	std::vector<int> result;
	if (type == 0)//! Node Set
	{
		for (int i = 0; i < nodeSetData.size(); i++)
		{
			if (strcmp(allNodeSetName[i].c_str(), setName.c_str()) == 0)
			{
				result.insert(result.end(), nodeSetData[i].begin(), nodeSetData[i].end());
			}
		}

		//for (int i = 0; i < nodeInternalSetData.size(); i++)
		//{
		//	if (strcmp(nodeInternalSetName[i].c_str(), setName.c_str()) == 0)
		//	{
		//		result.insert(result.end(), nodeInternalSetData[i].begin(), nodeInternalSetData[i].end());
		//	}
		//}
	}
	else if (type == 1)//! Element Set
	{
		for (int i = 0; i < elementSetData.size(); i++)
		{
			if (strcmp(allElementSetName[i].c_str(), setName.c_str()) == 0)
			{
				result.insert(result.end(), elementSetData[i].begin(), elementSetData[i].end());
			}
		}

		//for (int i = 0; i < elementInternalSetData.size(); i++)
		//{
		//	if (strcmp(elementInternalSetName[i].c_str(), setName.c_str()) == 0)
		//	{
		//		result.insert(result.end(), elementInternalSetData[i].begin(), elementInternalSetData[i].end());
		//	}
		//}
	}

	if (setInterMap.find(std::make_pair(type, setName)) != setInterMap.end())
	{
		std::vector<int>& setValue = setInterMap[std::make_pair(type, setName)];
		result.insert(result.end(), setValue.begin(), setValue.end());
	}

	sort(result.begin(), result.end());
	std::vector<int>::iterator iter = std::unique(result.begin(), result.end());
	result.erase(iter, result.end());
	return result;
}

std::vector<int> ReadINP::GetOutterSet(int type, std::string setName)
{
	std::vector<int> result;
	if (type == 0)//! Node Set
	{
		for (int i = 0; i < nodeSetData.size(); i++)
		{
			if (strcmp(allNodeSetName[i].c_str(), setName.c_str()) == 0)
			{
				result.insert(result.end(), nodeSetData[i].begin(), nodeSetData[i].end());
			}
		}

	}
	else if (type == 1)//! Element Set
	{
		for (int i = 0; i < elementSetData.size(); i++)
		{
			if (strcmp(allElementSetName[i].c_str(), setName.c_str()) == 0)
			{
				result.insert(result.end(), elementSetData[i].begin(), elementSetData[i].end());
			}
		}

	}


	sort(result.begin(), result.end());
	std::vector<int>::iterator iter = std::unique(result.begin(), result.end());
	result.erase(iter, result.end());
	return result;
}

std::vector<int> ReadINP::GetBusingSet(std::string setName)
{
	std::vector<int> result;
	for (int i = 0; i < bushingElementSetData.size(); i++)
	{
		if (strcmp(bushingElementSetName[i].c_str(), setName.c_str()) == 0)
		{
			result.insert(result.end(), bushingElementSetData[i].begin(), bushingElementSetData[i].end());
		}
	}

	sort(result.begin(), result.end());
	std::vector<int>::iterator iter = std::unique(result.begin(), result.end());
	result.erase(iter, result.end());
	return result;
}

std::vector<int> ReadINP::GetGapElementSet(std::string setName)
{
	std::vector<int> result;
	for (int i = 0; i < gapElementSetData.size(); i++)
	{
		if (strcmp(gapElementSetName[i].c_str(), setName.c_str()) == 0)
		{
			result.insert(result.end(), gapElementSetData[i].begin(), gapElementSetData[i].end());
		}
	}

	sort(result.begin(), result.end());
	std::vector<int>::iterator iter = std::unique(result.begin(), result.end());
	result.erase(iter, result.end());
	return result;
}

std::vector<int> ReadINP::GetDCOUP3DElementSet(std::string setName)
{
	std::vector<int> result;
	for (int i = 0; i < dcoup3dElementSetData.size(); i++)
	{
		if (strcmp(dcoup3dElementSetName[i].c_str(), setName.c_str()) == 0)
		{
			result.insert(result.end(), dcoup3dElementSetData[i].begin(), dcoup3dElementSetData[i].end());
		}
	}

	sort(result.begin(), result.end());
	std::vector<int>::iterator iter = std::unique(result.begin(), result.end());
	result.erase(iter, result.end());
	return result;
}


bool ReadINP::IfHaveSet(int type, std::string& setName)
{
	if (type == 0)//! Node Set
	{
		if (nodeSetNameMap.find(setName) != nodeSetNameMap.end())
		{
			return true;
		}

		for (int i = 0; i < nodeInternalSetData.size(); i++)
		{
			if (strcmp(nodeInternalSetName[i].c_str(), setName.c_str()) == 0)
			{
				return true;
			}
		}
	}
	else if (type == 1)//! Element Set
	{
		if (elementSetNameMap.find(setName) != elementSetNameMap.end())
		{
			return true;
		}

		for (int i = 0; i < elementInternalSetData.size(); i++)
		{
			if (strcmp(elementInternalSetName[i].c_str(), setName.c_str()) == 0)
			{
				return true;
			}
		}
	}
	return false;
}

void ReadINP::changeElementFormulation(std::string& setName, std::string targetFormulation)
{
	std::vector<int> elementIds = GetSet(1, setName);
	for (auto id : elementIds)
	{
		elementFormulation[id - 1] = targetFormulation;
	}
}

void ReadINP::addElementOrNode(int type, std::string& setName, int id)
{
	if (type == 0)//! Node Set
	{
		for (int i = 0; i < nodeSetData.size(); i++)
		{
			if (strcmp(allNodeSetName[i].c_str(), setName.c_str()) == 0)
			{
				int nodeIdInIBE = GetIBENodeIDFromINPID(id);
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + std::to_string(id) + " not found.");
					continue;
				}
				nodeSetData[i].emplace_back(nodeIdInIBE);
				return;
			}
		}
	}
	else if (type == 1)//! Element Set
	{
		for (int i = 0; i < elementSetData.size(); i++)
		{
			if (strcmp(allElementSetName[i].c_str(), setName.c_str()) == 0)
			{
				int ibeElementId = GetIBEElementIDFromINPID(id);
				if (ibeElementId == 0)
				{
					ReadINP::GetInstance()->warning.push_back("\nElement id " + std::to_string(id) + " not found.");
					continue;
				}
				elementSetData[i].emplace_back(ibeElementId);
				return;
			}
		}
	}
}



std::string ReadINP::ElementSetToNodeSet(std::string setName)
{
	std::vector<int> elementIds = GetSet(1, setName);
	if (elementIds.size() == 0)
	{
		return "";
	}

	int nodeNum = allElementType[elementIds[0] - 1] % 100;
	std::vector<int> nodeIds;
	nodeIds.resize(elementIds.size() * nodeNum);
	int nodeIndex = 0;
	for (auto elementId : elementIds)
	{
		int indexStart = elementIndex[elementId - 1];
		for (int i = 0; i < nodeNum; i++)
		{
			nodeIds[nodeIndex++] = allElementNode[indexStart + i];
		}
	}
	std::sort(nodeIds.begin(), nodeIds.end());
	auto iter = std::unique(nodeIds.begin(), nodeIds.end());
	nodeIds.erase(iter, nodeIds.end());
	AddSet(nodeIds, 0, setName + "_Node");
	return setName + "_Node";
}

int ReadINP::GetSetType(std::string setName)
{
	//! 输出的
	if (nodeSetNameMap.find(setName) != nodeSetNameMap.end())
	{
		return 0;
	}
	if (elementSetNameMap.find(setName) != elementSetNameMap.end())
	{
		return 1;
	}

	//! 内部的
	for (int i = 0; i < nodeInternalSetData.size(); i++)
	{
		if (strcmp(nodeInternalSetName[i].c_str(), setName.c_str()) == 0)
		{
			return 0;
		}
	}

	for (int i = 0; i < elementInternalSetData.size(); i++)
	{
		if (strcmp(elementInternalSetName[i].c_str(), setName.c_str()) == 0)
		{
			return 1;
		}
	}

	return -1;
}


std::string ReadINP::GetElementType(int elementIdIBE)
{
	return allElementTypeName[elementIdIBE - 1];
}

std::string ReadINP::GetSetElementType(const std::string setName)
{
	for (int i = 0; i < elementSetData.size(); i++)
	{
		if (strcmp(allElementSetName[i].c_str(), setName.c_str()) == 0)
		{
			if (elementSetData[i].size() == 0)
			{
#ifdef IBE_OS_WIN
				throw std::exception(("Set \"" + setName + "\" is empty.").c_str());
#elif defined(IBE_OS_LINUX)
				keyWordsUnsupport.emplace_back("Set \"" + setName + "\" is empty.");
				throw std::exception();
#endif
			}
			return allElementTypeName[elementSetData[i][0] - 1];
		}
	}

	for (int i = 0; i < elementInternalSetData.size(); i++)
	{
		if (strcmp(elementInternalSetName[i].c_str(), setName.c_str()) == 0)
		{
			if (elementInternalSetData[i].size() == 0)
			{
#ifdef IBE_OS_WIN
				throw std::exception(("Set \"" + setName + "\" is empty.").c_str());
#elif defined(IBE_OS_LINUX)
				keyWordsUnsupport.emplace_back("Set \"" + setName + "\" is empty.");
				throw std::exception();
#endif
			}
			return allElementTypeName[elementInternalSetData[i][0] - 1];
		}
	}
	return "";
}

void ReadINP::AddSet(std::vector<int>& idVec, int type, std::string setName, bool ifInpId)
{
	std::vector<int> ibeIdVec;
	ibeIdVec.resize(idVec.size());
	if (type == 0)
	{//! node
		if (ifInpId)
		{
			for (int j = 0; j < idVec.size(); j++)
			{
				int nodeIdInIBE = GetIBENodeIDFromINPID(idVec[j]);
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + std::to_string(idVec[j]) + " not found.");
					continue;
				}
				ibeIdVec[j] = nodeIdInIBE;
			}
			nodeSetNameMap[setName] = allNodeSetName.size();
			allNodeSetName.emplace_back(setName);
			nodeSetData.emplace_back(ibeIdVec);
		}
		else
		{
			nodeSetNameMap[setName] = allNodeSetName.size();
			allNodeSetName.emplace_back(setName);
			nodeSetData.emplace_back(idVec);
		}

	}
	else if (type == 1)
	{//! element
		if (ifInpId)
		{
			for (int j = 0; j < idVec.size(); j++)
			{
				int ibeElementId = GetIBEElementIDFromINPID(idVec[j]);
				if (ibeElementId == 0)
				{
					ReadINP::GetInstance()->warning.push_back("\nElement id " + std::to_string(idVec[j]) + " not found.");
					continue;
				}
				ibeIdVec[j] = ibeElementId;
			}
			elementSetNameMap[setName] = allElementSetName.size();
			allElementSetName.emplace_back(setName);
			elementSetData.emplace_back(ibeIdVec);
		}
		else
		{
			elementSetNameMap[setName] = allElementSetName.size();
			allElementSetName.emplace_back(setName);
			elementSetData.emplace_back(idVec);
		}
	}
}

void ReadINP::AddSet(std::vector<std::string>& idVec, int type, std::string setName)
{
	std::vector<int> ibeIdVec;
	ibeIdVec.reserve(idVec.size());
	std::vector<std::string> splitData;
	if (type == 0)
	{//! node
		for (int j = 0; j < idVec.size(); j++)
		{
			if (idVec[j].find(".") != std::string::npos)
			{
				GeneralMethod::split(splitData, idVec[j], ".");
				if (splitData.size() == 2)
				{
					int partThis = instanceToPart[splitData[0]];
					if (GeneralMethod::isNum(splitData[1]))
					{
						int nodeIdInIBE = GetIBENodeIDFromINPID(partThis, atoi(splitData[1].c_str()));
						if (nodeIdInIBE == 0)
						{
							ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + idVec[j] + " not found.");
							continue;
						}

						ibeIdVec.push_back(nodeIdInIBE);
					}
					else
					{
						std::vector<int> nodes = ReadINP::GetInstance()->GetInterSet(0, splitData[1]);
						ibeIdVec.insert(ibeIdVec.end(), nodes.begin(), nodes.end());
					}
				}
			}
			else if (GeneralMethod::isNum(idVec[j]))
			{
				int nodeIdInIBE = GetIBENodeIDFromINPID(atoi(idVec[j].c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + idVec[j] + " not found.");
					continue;
				}
				ibeIdVec.push_back(nodeIdInIBE);
			}
			else
			{
				std::vector<int> nodes = ReadINP::GetInstance()->GetSet(0, idVec[j]);
				ibeIdVec.insert(ibeIdVec.end(), nodes.begin(), nodes.end());
			}
		}

		sort(ibeIdVec.begin(), ibeIdVec.end());
		std::vector<int>::iterator iterNode = std::unique(ibeIdVec.begin(), ibeIdVec.end());
		ibeIdVec.erase(iterNode, ibeIdVec.end());

		nodeSetNameMap[setName] = allNodeSetName.size();
		allNodeSetName.emplace_back(setName);
		nodeSetData.emplace_back(ibeIdVec);
	}
	else if (type == 1)
	{//! element
		for (int j = 0; j < idVec.size(); j++)
		{
			if (idVec[j].find(".") != std::string::npos)
			{
				GeneralMethod::split(splitData, idVec[j], ".");
				if (splitData.size() == 2)
				{
					int partThis = instanceToPart[splitData[0]];
					if (GeneralMethod::isNum(splitData[1]))
					{
						int nodeIdInIBE = GetIBEElementIDFromINPID(partThis, atoi(splitData[1].c_str()));
						if (nodeIdInIBE == 0)
						{
							ReadINP::GetInstance()->warning.push_back("\nElement id " + idVec[j] + " not found.");
							continue;
						}

						ibeIdVec.push_back(nodeIdInIBE);
					}
					else
					{
						std::vector<int> nodes = ReadINP::GetInstance()->GetInterSet(0, splitData[1]);
						ibeIdVec.insert(ibeIdVec.end(), nodes.begin(), nodes.end());
					}
				}
			}
			else if (GeneralMethod::isNum(idVec[j]))
			{
				int nodeIdInIBE = GetIBEElementIDFromINPID(atoi(idVec[j].c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->warning.push_back("\nElement id " + idVec[j] + " not found.");
					continue;
				}
				ibeIdVec.push_back(nodeIdInIBE);
			}
			else
			{
				std::vector<int> nodes = ReadINP::GetInstance()->GetSet(0, idVec[j]);
				ibeIdVec.insert(ibeIdVec.end(), nodes.begin(), nodes.end());
			}
		}

		sort(ibeIdVec.begin(), ibeIdVec.end());
		std::vector<int>::iterator iterNode = std::unique(ibeIdVec.begin(), ibeIdVec.end());
		ibeIdVec.erase(iterNode, ibeIdVec.end());

		elementSetNameMap[setName] = allElementSetName.size();
		allElementSetName.emplace_back(setName);
		elementSetData.emplace_back(ibeIdVec);
	}
}

std::string ReadINP::GetSetOrAddSet(int type, std::string setName)
{
	if (GeneralMethod::isNum(setName))
	{
		std::string setNameReturn = setName;
		if (type == 0)
		{
			setNameReturn = setName + "_Node_Set";
		}
		else if (type == 1)
		{
			setNameReturn = setName + "_Element_Set";
		}
		if (!IfHaveSet(type, setNameReturn))
		{
			if (type == 0)
			{
				int nodeIdInIBE = GetIBENodeIDFromINPID(atoi(setName.c_str()));
				if (nodeIdInIBE == 0)
				{
					ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + setName + " not found.");
					return "";
				}
				std::vector<int> idsUsed{ nodeIdInIBE };
				AddSet(idsUsed, type, setNameReturn);
			}
			else if (type == 1)
			{
				int ibeElementId = GetIBEElementIDFromINPID(atoi(setName.c_str()));
				if (ibeElementId == 0)
				{
					ReadINP::GetInstance()->warning.push_back("\nElement id " + std::to_string(ibeElementId) + " not found.");
					return "";
				}
				std::vector<int> idsUsed{ ibeElementId };
				AddSet(idsUsed, type, setNameReturn);
			}
		}
		return setNameReturn;
	}
	else if (setName.find(".") != std::string::npos)
	{
		std::vector<std::string> trueName;
		GeneralMethod::split(trueName, setName, ".");
		if (trueName.size() == 2)
		{
			if (GeneralMethod::isNum(trueName[1]))
			{
				int partThis = instanceToPart[trueName[0]];			

				std::string setNameReturn = setName;
				if (type == 0)
				{
					setNameReturn = trueName[1] + "_Node_Set";
					if (!IfHaveSet(type, setNameReturn))
					{
						int nodeIdInIBE = GetIBENodeIDFromINPID(partThis, atoi(trueName[1].c_str()));
						if (nodeIdInIBE == 0)
						{
							ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nNode id " + trueName[1] + " not found.");
							return "";
						}
						std::vector<int> idsUsed{ nodeIdInIBE };
						AddSet(idsUsed, type, setNameReturn);
					}
				}
				else if (type == 1)
				{
					setNameReturn = trueName[1] + "_Element_Set";
					if (!IfHaveSet(type, setNameReturn))
					{
						int nodeIdInIBE = GetIBEElementIDFromINPID(partThis, atoi(trueName[1].c_str()));
						if (nodeIdInIBE == 0)
						{
							ReadINP::GetInstance()->keyWordsUnsupport.push_back("\nElement id " + trueName[1] + " not found.");
							return "";
						}
						std::vector<int> idsUsed{ nodeIdInIBE };
						AddSet(idsUsed, type, setNameReturn);
					}
				}
				return setNameReturn;
			}
			else
			{
				return	internalSetToOutSet(type, trueName[1]);
			}
		}
		else
		{
			return setName;
		}
	}
	else
	{
		return setName;
	}
}

//创建仿函数.判断排序后的两个容器的元素是否相同。
bool ReadINP::areEquivalent(const std::vector<int> vec1, const std::vector<int> vec2)
{
	if (vec1.size() != vec2.size())
	{
		return false;
	}
	std::vector<int> sortedVec1 = vec1;
	std::vector<int> sortedVec2 = vec2;
	std::sort(sortedVec1.begin(), sortedVec1.end());
	std::sort(sortedVec2.begin(), sortedVec2.end());
	return sortedVec1 == sortedVec2;
}

//获取inp中所有单元每个面的node map顺序。
void ReadINP::GetIbeElementNodeOfFaceAll()
{
	//将所有单元的FaceNode 存放到ibeElementNodeOfFaceAll容器中。
	for (int i = 1; i < cellId; i++)
	{
		int ibeElementId = i;
		int faceNumber = INP_card::FindFaceNumber(allElementTypeName[ibeElementId - 1]);
		if (faceNumber > 0)
		{
			for (int j = 0; j < faceNumber; j++)
			{
				std::vector<int> ibeElementNode = INP_card::GetFaceNode(allElementTypeName[ibeElementId - 1], j);
				for (int k = 0; k < ibeElementNode.size(); k++)
				{
					int nodeIndex = elementIndex[ibeElementId - 1];
					int nodeID = allElementNode[ibeElementNode[k] + nodeIndex - 1];
					ibeElementNode[k] = nodeID;
				}
				ibeElementNodeOfFaceAll.push_back(ibeElementNode);
				ibeElementNode.clear();
			}
		}
	}
}

int ReadINP::write_gmsh_file(string exe_path,string read_file_path,string write_file_path)
{
	Py_Initialize();
	PyObject* sys = PyImport_ImportModule("sys");
	PyObject* path = PyObject_GetAttrString(sys, "path");
	string py_file_path = exe_path;
	PyList_Append(path, PyUnicode_FromString(py_file_path.c_str()));

	PyObject* pModule = PyImport_ImportModule("WriteBDF");
	if (!pModule)
	{
		std::cout << "something wrong!\n";
		return -1;
	}

	PyObject* function = PyObject_GetAttrString(pModule, "write_gmsh");
	if (!function || !PyCallable_Check(function))
	{
		PyErr_Print();
		std::cout << "something wrong!\n";
		return -1;
	}

	PyObject* nodes_coord_py = PyList_New(allNodeCoor.size()/3);
	for (int i = 0; i < allNodeCoor.size(); i+=3)
	{
		vector<double> temp_data;
		temp_data.emplace_back(static_cast<double>(allNodeCoor[i]));
		temp_data.emplace_back(static_cast<double>(allNodeCoor[i+1]));
		temp_data.emplace_back(static_cast<double>(allNodeCoor[i+2]));
		
		PyObject* temp = GeneralMethod::change_vector_to_list(temp_data);
		PyList_SET_ITEM(nodes_coord_py, i/3, temp);
	}

	int element_id = 0;
	map<int, vector<int>> elements_points;
	PyObject* elements_points_py = PyDict_New();
	for (int i = 1; i < elementIndex.size(); i++)
	{
		elements_points[element_id].insert(elements_points[element_id].end(), allElementNode.begin() + elementIndex[i - 1], allElementNode.begin() + elementIndex[i]);
		element_id++;
	}
	elements_points_py = GeneralMethod::change_map_to_dict(elements_points);

	map<string, vector<int>> elements_sequence;
	PyObject* elements_sequence_py = PyDict_New();
	for (int i = 0; i < allElementType.size(); i++)
	{
		elements_sequence[abaqus_type_to_meshio_type[allElementType[i]]].emplace_back(i);
	}
	elements_sequence_py = GeneralMethod::change_map_to_dict(elements_sequence);

	auto pos = read_file_path.find_last_of('/');
	string file_name = read_file_path.substr(pos + 1);
	PyObject* file_name_py = PyUnicode_FromString(file_name.c_str());
	PyObject* write_file_path_py = PyUnicode_FromString(write_file_path.c_str());
	PyObject* res = PyObject_CallObject(function, PyTuple_Pack(5, nodes_coord_py, elements_points_py, elements_sequence_py, file_name_py, write_file_path_py));

	if (!res)
	{
		PyErr_Print();
	}

	return 1;
};

int ReadINP::write_vtk_file(string exe_path, string read_file_path, string write_file_path)
{
	allNodeCoor; elementIndex; allElementNode; allElementType;
	auto setVTKCELLTYPE = [&](vtkIdType* ele_index, vector<int>& _index)
	{
		for (size_t i = 0; i < _index.size(); i++)
		{
			ele_index[i] = static_cast<VTKCellType>(_index[i]);
		}
	};

	std::map<int, VTKCellType> inp_to_vtk_type =
	{
		std::make_pair(001, VTK_VERTEX),
			std::make_pair(102, VTK_LINE),
			std::make_pair(203, VTK_TRIANGLE),
			std::make_pair(204, VTK_QUAD),
			std::make_pair(206, VTK_QUADRATIC_TRIANGLE),
			std::make_pair(208, VTK_QUADRATIC_QUAD),
			std::make_pair(304, VTK_TETRA),
			std::make_pair(306, VTK_WEDGE),
			std::make_pair(308, VTK_HEXAHEDRON),
			std::make_pair(310, VTK_QUADRATIC_TETRA),
			std::make_pair(315, VTK_QUADRATIC_WEDGE),
			std::make_pair(320, VTK_QUADRATIC_HEXAHEDRON),
			
	};

	vtkNew<vtkPoints> all_points;
	for (int i = 0; i < allNodeCoor.size(); i+=3)
	{
		all_points->InsertNextPoint(allNodeCoor[i], allNodeCoor[i+1], allNodeCoor[i+2]);
	}
	vtkNew<vtkUnstructuredGrid> Grid;
	Grid->SetPoints(all_points);
	for (int i = 0; i < allElementType.size(); i++)
	{
		if (allElementType[i]!=102 && allElementType[i] != 204)
		{
			int tesst = 1;
		}
		VTKCellType cell_type = inp_to_vtk_type[allElementType[i]];
		int start = elementIndex[i];
		int end = elementIndex[i+1];
		vector<int> ele_nodes(allElementNode.begin()+start, allElementNode.begin()+end);
		for (auto&j: ele_nodes)
		{
			j -= 1;
		}
		vtkIdType* ele_index = new vtkIdType[ele_nodes.size()];
		/*for (size_t k = 0; k < ele_nodes.size(); k++)
		{
			ele_index[k] = static_cast<VTKCellType>(ele_nodes[k]);
		}*/
		setVTKCELLTYPE(ele_index, ele_nodes);
		Grid->InsertNextCell(cell_type, ele_nodes.size(), ele_index);

	}
	vtkNew<vtkXMLUnstructuredGridWriter> writer;
	writer->SetInputData(Grid);
	auto pos = read_file_path.find_last_of('/');
	auto pos2 = read_file_path.find_last_of('.');
	string file_name = read_file_path.substr(pos + 1, pos2 - pos - 1);
	writer->SetFileName((write_file_path + "/" + file_name + ".vtu").c_str());
	writer->Write();
	return 1;

};

int ReadINP::write_gmsh_file_from_vtk(std::string exe_path, std::string read_file_path, std::string write_file_path) 
{
	Py_Initialize();
	//PyRun_SimpleString("import sys;print(dir(sys.path))");
	PyObject* sys = PyImport_ImportModule("sys");
	PyObject* path = PyObject_GetAttrString(sys, "path");
	string py_file_path = exe_path;
	PyList_Append(path, PyUnicode_FromString(py_file_path.c_str()));

	PyObject* pModule = PyImport_ImportModule("WriteBDF");
	if (!pModule)
	{
		std::cout << "something wrong!\n";
		return -1;
	}
	PyObject* function = PyObject_GetAttrString(pModule, "write_gmsh_from_vtk");
	if (!function || !PyCallable_Check(function))
	{
		PyErr_Print();
		std::cout << "something wrong!\n";
		return -1;
	}

	string file_name = read_file_path.substr(read_file_path.find_last_of("/") + 1);
	string file_name_without_suffix = file_name.substr(0, file_name.find_last_of("."));
	PyObject* vtk_path_py = PyUnicode_FromString((write_file_path + "/" + file_name_without_suffix + ".vtu").c_str());
	PyObject* write_file_path_py = PyUnicode_FromString((write_file_path + "/" + file_name_without_suffix + ".msh").c_str());
	PyObject* res = PyObject_CallObject(function, PyTuple_Pack(2, vtk_path_py, write_file_path_py));
	if (!res)
	{
		PyErr_Print();
		cout << "[ERROR] CallObject throw a exception" << endl;
		Py_Finalize();      // 释放资源
		return -1;
	}
	Py_Finalize();
	return 0;
};
